问题描述
为什么接下来的两个模板声明不明确(所以没有一个比另一个更专业)?我知道在Stack Overflow上已经多次提出这个问题,但通常人们会回答如何解决歧义,而不是为什么会发生歧义。
Why are the next two template declarations ambiguous (so neither is more specialized than the other)? I know this question has been raised many times on Stack Overflow, but usually, people answer how to resolve ambiguity, not why it's happened.
I。
模板< class T> void func(char * buf,T size){}
II。
模板< std :: size_t N> void func(char(& buf)[N],std :: size_t大小){}
试图通过C的步骤++ 14解决部分功能模板排序的标准(14.5.6.2):
Trying to pass steps of the C++14 standard to resolve partial function template ordering (14.5.6.2):
转换后的函数模板的函数类型为: void func(char *,U1)
,其中 U1
是某些唯一的合成类型。
Transformed function I template's function type is: void func(char*, U1)
, where U1
is some unique synthetic type.
转换后的函数II模板的函数类型为: void func(char(& buf)[N1],std :: size_t)
,其中 N1
是唯一的综合值。
Transformed function II template's function type is: void func(char (&buf)[N1], std::size_t)
, where N1
is some unique synthetic value.
所以让我们尝试在一侧执行类型推导(将第一个模板用作参数,将第二个模板用作参数模板),并放在另一侧。
So let's try to perform type deduction on one side (using the first template as an argument and the second one as a parameter template) and on the opposite side.
参数模板: template< std :: size_t N> void func(char(& buf)[N],std :: size_t大小)
。
转换后的参数模板: void func(char *,U1)
。
试图推导模板参数。无法从 char *
类型推导出 char(& buf)[N]
。 U1也不匹配 std :: size_t
类型。
Trying to deduce template parameters. "char (&buf)[N]
" can't be deduced from "char*
" type. U1 doesn't match std::size_t
type either. Failed.
参数模板: template< class T> void func(char * buf,T size)
。
转换后的参数模板: void func(char(& buf)[N1],std :: size_t)
。
试图推断模板参数。参数模板的第一个参数完全没有类型,并且与 char []
兼容。 T
应该推导为 std :: size_t
。
Trying to deduce template parameters. The first argument of parameter template is not type at all and it's compatible with a char[]
. T
should be deduced to std::size_t
.
因此,模板II应该更加专业,并应在以下代码中进行选择:
So template II should be more specialized and should be selected in the following code:
char buf[16];
func(buf, static_cast<std::size_t>(16));
为什么对于GCC 5.3和Clang 4.0并非如此?
Why is this not true for GCC 5.3 and for Clang 4.0?
推荐答案
模板声明不是模棱两可;以下代码将编译并运行正常:
The template declarations are not ambiguous; the following code compiles and runs OK:
#include <iostream>
#include <string>
using namespace std;
template<class T>
void func(char* buf, T size) {cout<<"void func(char*,T)\n";}
template<size_t N>
void func(char (&buf)[N], std::size_t size) {
cout<<"void func(char (&)[],size_t)\n";}
int main() {
char buf[3];
func(buf, 2);
func<3>(buf, 2);
func(reinterpret_cast<char (&)[3]>(buf), 2);
//next is ambiguous
//func(reinterpret_cast<char (&)[3]>(buf), size_t(2));
func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));
return 0;
}
但是,被注释掉的调用是模棱两可的。要消除歧义,请使用:
However, the commented-out call is ambiguous. To disambiguate it use:
func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));
此方法正常,并调用正确的函数。
This works OK and calls the correct function.
这篇关于为什么按照GCC 5.3和Clang 4.0,接受数组的C ++模板不比接受指针的模板更专业?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!