转发非引用类型的引用

时间:2017-12-09 08:57:08

标签: c++

 template<typename T>
 void F(T&& x) {}

如果我们用int&amp;类型的参数调用它一切都很清楚 - 参考崩溃发生,我们仍然有左值参考。但是如果我们用例如int参数调用它会发生什么。我的想法:我们推导出类型T = int,用rvalue-reference来装饰它,所以F取int&amp;&amp;参数并使用int类型调用它将导致错误。但在实际F中,这种论证就像左值引用一样。左值参考来自哪里?编译器适用于什么规则来获得int&amp;来自int?

2 个答案:

答案 0 :(得分:1)

从C ++ 17开始,C ++标准中存在转发引用的概念。通常,模板参数被推断为非参考。但是对于转发引用的特定情况,如果相应的参数是左值,则将该参数推导为引用。 C++ standard (N4700)[temp.over.deduct.call]/3

  

[...] 转发引用是对cv-unqualified模板参数的右值引用,该参数不表示类模板的模板参数(在类模板参数推断期间[[over]。 match.class.deduct]))。如果P是转发引用且参数是左值,则使用类型“左值引用A”代替A来进行类型扣除。[...]

对于函数调用的关注,它与C++11(N337)C++14(N414) [temp.over.deduct.call] / 3中的等效段落具有相同的含义:

  

[...]如果P是对cv-unqualified模板参数的右值引用,并且参数是左值,则使用类型“左值引用A”来代替A进行类型推导[...]

答案 1 :(得分:0)

转发引用推导出左值的左值引用和右值的左值引用。例如,即使对于int&&类型的左值,它仍然会推导int&(对于int类型的左值),同样,对于类型为intint&&的rvalues 会推断出int&&

template<typename T>
class show;

template<typename T>
void F(T&& x) 
{ show<decltype(x)>();}

int main() {
    int&& x = 5;
    F(x);
}
main.cpp:6:3: error: implicit instantiation of undefined template 'show<int &>'
int main() {
    F(5);
}
main.cpp:6:3: error: implicit instantiation of undefined template 'show<int &&>'
int main() {
    int x = 5;
    F(x);
}
main.cpp:6:3: error: implicit instantiation of undefined template 'show<int &>'
int main() {
    F([]()->int{return 5;}());
}
main.cpp:6:3: error: implicit instantiation of undefined template 'show<int &&>'