fre*_*low 10 c++ templates const reference instantiation
好吧,这可能看起来像一个愚蠢的问题,但它在这里:
template <typename T>
void foo(T& x)
{
}
int main()
{
foo(42);
// error in passing argument 1 of 'void foo(T&) [with T = int]'
}
Run Code Online (Sandbox Code Playgroud)
是什么阻止C++实例化实例化foo函数模板T = const int?
问题是模板类型推导必须计算完全匹配,并且在特定情况下,由于签名中的引用,完全匹配需要左值.值42,是不是左值,而是一个右值,并解决T与const int不会产生一个完美的匹配.由于模板类型扣除仅限于完全匹配,因此不允许扣除.
如果不是使用文字而是使用非可变左值,那么编译器将推导出适当的类型,因为const int它将成为参数的完美匹配:
const int k = 10;
foo( k ); // foo<const int>( const int & ) is a perfect match
Run Code Online (Sandbox Code Playgroud)
现在有一个特殊的规则,它允许调用一个带有r值的const引用(不可变的左值)的函数,这意味着创建一个临时的左值,后来绑定到引用,但是该规则要启动函数必须事先有那个签名,这就是明确说明模板类型const int有效的原因:foo<const int>(42).