Const参数绑定到C ++模板中的非const引用

时间:2014-02-05 09:42:40

标签: c++ templates reference const

考虑类似的事情:

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 ++模板规则背后的基本原理是什么?

3 个答案:

答案 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。