考虑类似的事情:
template <typename T>
void f(T& x)
{
....
}
为什么 const
int
会绑定到f(T&)
?
在我看来,这种情况违反了 const-correctness 。事实上,如果f()
采用非 -const T&
引用,那么f()
很可能修改其参数(否则,f()
将被定义为void f(const T&)
)。
在这样的代码中:
template <typename T>
inline void f(T& x)
{
x = 0;
}
int main()
{
int n = 2;
f(n);
const int cn = 10;
f(cn);
}
编译器尝试使用f()
来调用T = const int
,然后由于x = 0;
正文中的f()
分配,会出现错误消息。
这是来自GCC的错误消息:
test.cpp: In instantiation of 'void f(T&) [with T = const int]': test.cpp:13:9: required from here test.cpp:4:7: error: assignment of read-only reference 'x' x = 0; ^
但是为什么编译器会尝试将 const 参数绑定到一个带有非 -const参数的函数模板?
此C ++模板规则背后的基本原理是什么?
答案 0 :(得分:8)
T
绑定到const int
。
为避免这种情况,您可以使用SFINAE:
template<typename T>
typename std::enable_if<!std::is_const<T>::value, void>::type
f(T& arg) {}
或已删除功能:
template <typename T> void f(T& arg) {}
template <typename T> void f(const T&) = delete;
答案 1 :(得分:3)
您可以使用std::enable_if
加上例如std::is_const
以避免T
绑定到const
类型。
重新......
“这个C ++模板规则背后的理由是什么?”
它可以在Bjarne的设计和进化书中找到,但关于最常见的理由是,规则是为了简单和统一而选择的,因此它似乎也在这里:以特殊方式处理某些类型会引入不必要的复杂性。
答案 2 :(得分:0)
const int cn = 10;
这意味着'cn'是const,你不能随时随地改变它。
更多:
const int cia = 10;
int ia = 10;
cia的类型与ia不同。所以T将是const int,而不是int。
typedef const int cint;
cint cia = 10;
int ia = 10;
T将用作cint,而不是int。