忽略了部分函数特化中值类型的顶级const限定符

时间:2012-10-31 16:05:34

标签: c++ c++11

由于const int专业化导致以下错误:

#include <iostream>
using std::cout;
using std::endl;

template <typename T> void g(T val)
{
    cout << "unknown" << endl;
}

template <> void g(int && val)
{
    cout << "int &&" << endl;
}

template <> void g(const int && val)
{
    cout << "const int &&" << endl;
}

template <> void g(int & val)
{
    cout << "int &" << endl;
}

template <> void g(const int & val)
{
    cout << "const int &" << endl;
}

template <> void g(int val)
{
    cout << "int" << endl;
}

template <> void g(const int val)  //redefinition here
{
    cout << "const int" << endl;
}

int main() {}

error: redefinition of 'g'
template <> void g(const int val)
                 ^

为什么T&T&&const T&const T&&不同,但Tconst T不同?

2 个答案:

答案 0 :(得分:6)

因为函数参数的顶级常量是函数的实现细节。例如,以下内容有效:

// Prototype
void foo(int c);

// Implementation
void foo(int const c) { ... }

由于参数是按值传递的,因此调用者并不真正关心函数是否要修改自己的私有副本。因此,顶级常量不是函数签名的一部分。

请注意,这仅适用于顶级常量! intint const在函数原型中是等效的,int *int * const也是如此。但int *int const *不是。

答案 1 :(得分:0)

使用参数时,需要考虑以下几点:A:不通过引用传递参数是创建自己的新变量,而B:按引用传递使用与具有不同名称的参数相同的变量< / p>

这很重要,因为:

void doStuff (const int x)
{
    //x is its own constant variable
}

尽管

void doStuff (const int& x)
{
    //because x is the same variable that was used when calling this function
    //x can be modified outside of this function, but not inside the function
    //due to the const modifier
}

第二个函数的const修饰符允许你做这样的事情:

int main ()
{
    const int x = 10;
    doStuff(x)
}

引用用于修改另一个函数中的变量并将内存保存在堆栈中,这节省了内存,因为它使用指针而不是新创建的变量,因此任何大于int的内容都将通过使用引用调用来节省内存即使你没有在函数中修改它

现在,如果我是正确的&amp;&amp;不应在参数中使用运算符,因为这是一个布尔运算符,不会修改参数类型。它只应该在条件中使用,但在编译时不会产生语法错误(编译器认为它是[type]&amp;类型的引用)但除了花费更长的时间用于计算机处理之外,它对变量的使用方式没有任何作用/ p>