从右值参数推导出对 const 的引用
好吧,这似乎是一个愚蠢的问题,但它是这样的:
模板<typename T>无效 foo(T&x){}主函数(){富(42);//传递 'void foo(T&) [with T = int]' 的参数 1 时出错}
是什么阻止了 C++ 用 T = const int
来实例化 foo
函数模板?
问题是模板类型推导必须计算出精确匹配,而在这种特殊情况下,由于签名中的引用,精确匹配需要一个左值.值 42 不是左值,而是右值,用 const int
解析 T
不会产生完美匹配.由于模板类型扣除仅限于完全匹配,因此不允许扣除.
如果您使用非可变左值而不是使用文字,那么编译器将适当地推断类型,因为 const int
将成为参数的完美匹配:
const int k = 10;富(k);//foo<const int>( const int & ) 是完美匹配
现在有一个特殊规则允许调用一个函数,该函数接受一个带有右值的 const 引用(非可变左值),这意味着创建一个稍后绑定到该引用的临时左值,但该规则在函数必须事先具有该签名,这就是为什么明确声明模板的类型是 const int
有效:foo
.p>
Okay, this may seem like a silly question, but here it goes:
template <typename T>
void foo(T& x)
{
}
int main()
{
foo(42);
// error in passing argument 1 of 'void foo(T&) [with T = int]'
}
What is preventing C++ to instantiate the foo
function template with T = const int
instead?
The problem is that template type deduction has to work out an exact match, and in that particular case, because of the reference in the signature, an exact match requires an lvalue. The value 42, is not an lvalue, but rather an rvalue, and resolving T
with const int
would not yield a perfect match. Since template type deduction is limited to exact matches, that deduction is not allowed.
If instead of using a literal you use a non mutable lvalue, then the compiler will deduce the type appropriatedly, as const int
will become a perfect match for the argument:
const int k = 10;
foo( k ); // foo<const int>( const int & ) is a perfect match
Now there is a special rule that enables calling a function that takes a const reference (nonmutable lvalue) with an rvalue, that implies creation of a temporary lvalue which is later bound to the reference, but for that rule to kick in the function has to have that signature before hand, which is why explicitly stating that the type of the template is const int
works: foo<const int>(42)
.
相关文章