为什么 T& 类型的模板函数参数可以绑定到常量左值而不是右值?
Why can template function parameters of type T& be binded to const lvalues but not rvalues?
考虑:
template <typename T> void f(T&);
const int b = 2;
f(b); // ok
f(2); // error, can not bind rvalue to lvalue reference
为什么允许f(const int)
?逻辑似乎表明,如果程序员没有将模板参数明确定义为const T&
,他/她希望修改绑定到变量。
因此,在这种情况下,问题是,为什么模板实例化给自己提供了用常量实例化的自由,而这些常量并不是明确需要的?
即使允许模板实例化使用常量是有道理的,那么在这种情况下,为什么要禁止绑定到右值呢?您可以将右值绑定到常量左值引用。在这种情况下,模板将被实例化为f<const int>
,并且f(2)
将被允许。
我想知道这些决定背后的原因,而不是参考标准。
为什么允许f(const int)?
您可以用const int
替换模板T
,将T&
转换为const int&
即使有允许模板实例化使用常量的理由,那么在这种情况下,为什么会禁止绑定到右值?
没有T
(在T&
中)与int&&
(完全)匹配以进行推导。
f<const int>(42)
是允许的,但没有发生任何扣除。
我想知道这些决定背后的原因,而不是对标准的引用。
那么为什么允许在模板中进行cv替换呢
我想说它使通用编程更容易
否则,必须为const
、volatile
的每个组合提供过载。
在这里,如果你想将T
限制为非const
,你可以使用具有特征的SFINAE:
template <typename T> std::enable_if_t<!std::is_const<T>::value> f(T&);
因此,在这种情况下,问题是,为什么模板实例化在没有明确要求常量的情况下给自己实例化常量的自由?
很简单,f
的实现中没有任何东西阻止用const int
实例化模板。请尝试以下操作,您会发现问题。
template <typename T> void f(T& v) { v = 3; };
const int b = 2;
f(b); // error: assignment of read-only reference (within the template instance)
int c = 2;
f<const int>(c); // error
b是const int
的事实意味着模板被实例化为<const int>
,这是不可能的,因为v
被修改了。类似地,不允许作为<const int>
的显式实例化。
为什么它被推导为
const int
?它应该被推导为CCD_ 24。
如果没有明确指定实例化模板的类型,则会根据传递到函数中的类型const int
来推导。期望它推导出一个不同的类型是不切实际的(如果不是完全荒谬的话)。
还请注意,如果它确实将类型推导为int
,那么将const int
传递到函数中会出现错误。这可以通过将模板显式实例化为<int>
来证明。
template <typename T> void f(T&) {};
const int b = 2;
f<int>(b); //error: no matching function for call to 'f<int>(const int&)
在这种情况下,为什么要绑定到被禁止的右值?
编译器需要隐式地假设一个合适的类型来实例化模板,然后执行从右值到常量左值引用的隐式转换。(对我来说,这似乎是一种奢望。)
请注意,如果您将模板显式实例化为<const int>
,那么将右值绑定到常量左值引用是有效的,因为可以完成转换。
template <typename T> void f(T&);
f<const int>(2); // OK
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将常量指针引用绑定到非常量指针
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 未定义的对象(〔basic.life〕/8):为什么允许引用重新绑定(和常量修改)
- 为什么右值不能绑定到非常量左值引用,除了写入临时无效的事实?
- 为什么我不能将常量左值引用绑定到返回 T&&&的函数?
- 出于什么原因,有必要将常量左值引用绑定到右值?
- 对类型的非常量左值引用无法绑定到类型为"*"的临时
- 返回非常量引用会导致绑定引用错误
- std::tie 在从函数调用传递值时失败,并显示"无法绑定非常量左值引用"
- 为什么静态常量字符 * const 变量在为左值时可绑定到右值引用参数
- 从函数返回引用与临时绑定到常量引用
- 无法将类型为"类名 &"的非常量左值引用绑定到类型为"类名"的右值
- 为什么临时对象可以绑定到常量引用?
- 对类型 'A *' 的非常量左值引用不能绑定到不相关的类型 'std::shared_ptr<A>' 的值
- 某些内容可以绑定到非常量引用但不能绑定到常量引用的情况
- 当常量引用参数绑定到右值时,右值是否保持其"status"?
- Arduino代码导致CurieBLE的c++中出现非常量绑定错误
- 这是引用到非常量绑定到临时的实例吗?