用const实参重载实参演绎的c++模板函数
c++ template function overlading argument deduction with const argument
我有以下设置:
template <typename T>
void foo(T& t);
void foo(const int& t);
void f()
{
int i;
foo(i); //Unresolved reference to "void foo<int>(int &)"
foo(const_cast<const int&>(i)); //Unresolved reference to "void foo(int const &)"
}
在第一次调用foo时,编译器尝试调用模板版本,因为非模板版本的实参与i的类型不匹配。在第二次调用中,调用非模板版本。我使用的是微软c++编译器版本10。这是标准行为吗?如果类型不完全匹配,即使只有const修饰符,也会调用模板函数。
编辑:我知道这两个函数没有定义,我只是指出链接器抱怨什么,让它更清楚编译器想要调用什么
是,根据c++ 11标准,此行为是正确的。
在第一种情况下,实参是对非const
整数的引用。这两种重载都可以解析此调用,但函数模板允许完全匹配,而非模板重载则需要进行限定转换。
在第二种情况下,两者是完美匹配的,但是其中一个重载是而不是函数模板,因此它比函数模板更好。根据§13.3.3/1,事实上:
给定这些定义,一个可行函数F1被定义为比另一个可行函数更好的函数F2如果对于所有参数i, ICSi(F1)不是比ICSi(F2)更差的转换序列,然后
-对于某些参数j, ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是,
——上下文是用户自定义转换的初始化(参见8.5、13.3.1.5和13.3.1.6)从返回类型F1到目的类型(即,类型)的标准转换序列实体被初始化)是一个比标准转换序列更好的转换序列将F2的返回类型转换为目标类型。[…]或者,如果不是,
- F1是非模板函数,F2是函数模板专门化,如果不是,则
— [...]
这是标准行为吗?如果类型不完全匹配,即使只有const修饰符,也会调用模板函数。
是的,这是由标准定义的。
如果没有精确匹配,则使用模板,因为实例化的模板版本总是比需要转换的模板版本更好的匹配(即使是int &
到int const&
转换)
应该可以了
#include <iostream>
template <typename T>
void foo(T& t) {}
void foo(const int& t){}
void f()
{
int i;
foo(i); //Unresolved reference to "void foo<int>(int &)"
foo(const_cast<const int&>(i)); //Unresolved reference to "void foo(int const &);
}
int main()
{
f();
}
- 非类型引用形参/实参
- 成员函数指针的模板实参演绎
- 函数和函数作为模板函数的实参
- Const到非Const指针模板实参的转换
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 当实参是初始化列表而形参是引用时,重载解析
- 函数模板中返回类型的模板实参演绎
- ostream_iterator的模板实参-每个元素都是pair
- c++——关于使用默认实参的困惑
- std::shared_ptr、继承和模板实参演绎的问题
- 将操作符转换为模板实参的特化
- 使用模板模板形参时,模板实参推导失败
- 带有const实参的c++构造函数
- 函数指针作为模板实参而不是函子
- c++临时对象绑定到实参并返回const引用值
- 调用对象作为默认实参的this
- 当涉及一个重载函数作为实参时,模板实参推导是如何工作的
- c++对const引用的实参依赖没有改变
- 为什么模板非类型形参指针和引用实参需要是全局的
- 将函数形参的实参解包到c++模板类