Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数的隐式转换规则_C++_Templates_Overloading - Fatal编程技术网

C++ 模板参数的隐式转换规则

C++ 模板参数的隐式转换规则,c++,templates,overloading,C++,Templates,Overloading,如果您重载一个函数,然后使用与其中一个重载完全匹配的参数调用它 int f(int){return 3;} int f(bool){return 4;} ... //inside main() f(1); //Calls f(int) 编译器只需在尝试任何隐式转换之前选择此(完美)匹配。然而,我一直在尝试重载函数tempĺate,如中所示 template <bool veracity> int f(){return 1;} template <in

如果您重载一个函数,然后使用与其中一个重载完全匹配的参数调用它

int f(int){return 3;}
int f(bool){return 4;}
...        //inside main()
f(1);      //Calls f(int)
编译器只需在尝试任何隐式转换之前选择此(完美)匹配。然而,我一直在尝试重载函数tempĺate,如中所示

template <bool veracity>
int f(){return 1;}

template <int amount>
int f(){return 2;}

...        //inside main()
f<1>();
模板
int f(){return 1;}
模板
int f(){return 2;}
...        //内干管()
f();
但是编译器不断抱怨对重载f()的调用不明确,指出它可能是
f()
f()
。编译器不应该选择完美匹配,而不是尝试将1转换为true吗


我的印象是,模板参数的隐式转换实际上比函数参数的隐式转换更具限制性。有没有办法解决这个问题?

您提供的参数不是类型,而是值,因此规则有点不同——您需要将规则应用于非类型参数。对于非类型参数,允许隐式转换。§14.3.2/5:

对用作非类型模板参数的每个表达式执行以下转换。如果无法将非类型模板参数转换为相应模板参数的类型,则程序的格式不正确

-对于整型或枚举型的非类型模板参数,将应用转换后的常量表达式(5.19)中允许的转换

在C++03中,措辞略有不同,但效果基本相同(同样是§14.3.2/5):

-对于整型或枚举型的非类型模板参数,将应用整型升级(4.5)和整型转换(4.7)


无论哪种方式,由于
1
既是
int
又可以隐式转换为
bool
,因此您的调用是不明确的。

因为这不是一个编译器错误,而是一个语言功能(请参阅),您必须找到解决方法

您必须重命名您的函数,或者您可以使用以下方法:

template <typename T> struct F;

template<> struct F<bool> {
  template <bool veracity>
  static int f(){return 1;}
};

template<> struct F<int> {
  template <int amount>
  static int f(){return 2;}
};

template <typename T, T value>
int f() { return F<T>::template f<value>(); }

// inside main():
std::cout << f<int,  2>() << '\n'; // prints 2
std::cout << f<bool, 2>() << '\n'; // prints 1
模板结构F;
模板结构F{
模板
静态int f(){return 1;}
};
模板结构F{
模板
静态int f(){return 2;}
};
模板
int f(){return f::template f();}
//内干管():

我看不出来。你知道规则是这样的有什么特别的原因吗?我的意思是,是否有一些技术上的困难或事情会使编译器将“精确匹配第一/隐式转换第二”逻辑(用于函数参数)应用于模板参数变得不实用?不,我不确定。我的猜测是,这主要是因为规则已经很复杂了,添加一组“排名”规则(就像重载规则一样)会使它们更加复杂。我不确定,但我猜由于与其他模板规则的交互作用,排名规则最终也会与重载规则略有不同,因此这不仅仅是说“候选函数将形成一个重载集,根据§13.3解决。”