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