为什么此模板扩展在C ++中合法?

时间:2018-10-21 04:13:07

标签: c++ templates generics types template-deduction

考虑以下代码:

template <typename T>
void foo(const T& param) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    std::cout << param;
}

int main()
{
    foo<const int&>(5);
    return 0;
}

输出给出:

void foo(const T&) [with T = const int&]                                                                                                                       
5 

显然T解析为const int&(如打印输出所述,因为我明确地强迫这样做)。但是,这似乎产生了一个问题:函数签名采用类型为const T&的参数,在这种情况下,它将扩展为const const int& &,这在C ++中不是合法的语法。

但是程序确实运行良好。这里发生了什么?

更新: 我知道T& &会崩溃为T&。但是,在这种情况下,如果您明确地写成双const也是不合法的,而且我看不到模板折叠规则会提及这一部分。

更新2: 编译const const int x = 1;得到error: duplicate ‘const’。在c ++中不允许使用多个const(但令人惊讶的是,在c中还可以)。

1 个答案:

答案 0 :(得分:5)

C ++类型不是通过文本替换形成的。 const T&其中Tvoid *的是void* const &,而不是const void *&

您的代码尝试形成类型“对const T的左值引用”,其中T是“对const int的左值引用”。通过the reference collapsing rules,它将形成类型“对const int的左值引用”。