Vya*_*yev 15 c++ templates standards-compliance partial-ordering c++11
为什么接下来的两个模板声明不明确(所以两者都不比另一个更专业)?我知道这个问题已经在Stack Overflow上多次提出,但通常,人们会回答如何解决歧义,而不是为什么会发生这种情况.
一世.
template <class T> void func(char* buf, T size) {}
II.
template <std::size_t N> void func(char (&buf)[N], std::size_t size) {}
尝试传递C++ 14标准的步骤来解决部分函数模板排序(14.5.6.2):
要生成转换模板,对于每种类型,非类型或模板模板参数(包括其模板参数包(14.5.3))分别合成唯一类型,值或类模板,并将其替换为该参数的每次出现在模板的函数类型中.
转换函数我模板的函数类型是:void func(char*, U1)
,其中U1
是一些独特的合成类型.
转换函数II模板的函数类型是:void func(char (&buf)[N1], std::size_t)
,其中N1
是一些独特的合成值.
使用转换后的函数模板的函数类型,对14.8.2.4中描述的其他模板执行类型推导.
因此,让我们尝试在一侧执行类型推导(使用第一个模板作为参数,第二个模板作为参数模板),在另一侧.
参数模板:template <std::size_t N> void func(char (&buf)[N], std::size_t size)
.转换参数模板:void func(char*, U1)
.
试图推断出模板参数." char (&buf)[N]
"不能从" char*
"类型中推断出来.U1也与std::size_t
类型不匹配.失败.
参数模板:template <class T> void func(char* buf, T size)
.转换参数模板:void func(char (&buf)[N1], std::size_t)
.
试图推断出模板参数.参数模板的第一个参数根本不是类型,它与a兼容char[]
.T
应该推断出来std::size_t
.
所以模板II应该更专业,应该在以下代码中选择:
char buf[16];
func(buf, static_cast<std::size_t>(16));
Run Code Online (Sandbox Code Playgroud)
为什么GCC 5.3和Clang 4.0不适用?
小智 1
模板声明没有歧义;以下代码编译并运行正常:
#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;
}
Run Code Online (Sandbox Code Playgroud)
然而,注释掉的调用是不明确的。要消除歧义,请使用:
func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));
Run Code Online (Sandbox Code Playgroud)
这工作正常并调用正确的函数。
归档时间: |
|
查看次数: |
670 次 |
最近记录: |