转发非引用类型的引用
Forwarding references for non-reference types
template<typename T>
void F(T&& x) {}
如果我们用 int 类型的参数调用它,一切都很清楚 - 引用崩溃发生,我们仍然有左值引用。但是,如果我们用例如 int 参数来调用它会发生什么。我的想法:我们已经推导出了类型T=int,用右值引用装饰它,所以F采用int&&argument,用int类型调用它会导致错误。但在现实中,F将这样的论点作为左值引用。左值引用从何而来?编译器应用了哪些规则来从 int 获取 int&?
自 C++17 年以来,C++标准中就有了转发引用的概念。通常,模板参数被推断为非引用。但是对于转发引用的特定情况,如果相应的参数是左值,则该参数被推导为引用。C++标准 (N4700)[温度超过.扣除调用]/3:
[...]转发引用是对 cv 非限定模板参数的右值引用,该参数不表示类模板的模板参数(在类模板参数推导期间 ([over.match.class.deduct]))。如果 P 是转发引用,参数是左值,则使用类型"对 A 的左值引用"代替 A 进行类型推断。[...]
对于函数调用的问题,它与 C++11(N337) 和 C++14(N414) [temp.over.deduct.call]/3 中的等效段落具有相同的含义:
[...]如果 P 是对 cv 非限定模板参数的右值引用,并且参数是左值,则使用类型"对 A 的左值引用"代替 A 进行类型推导[...]
转发引用推导出左值的左值引用和右值的右值引用。例如,即使对于int&&
类型的左值,它仍然会推导出int&
(就像对于int
类型的左值一样),同样,对于int
或int&&
类型的右值,它将推导出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 &&>'
相关文章:
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- 只有"void"是不可引用的类型吗?
- 成员引用基类型 'char' 不是 C++ 中的结构或联合
- 具有引用返回类型的重写方法上的协变返回类型无效
- 直接在 C++ 中将值分配给引用返回类型
- 成员引用基类型不是结构或联合
- for 循环说 - 错误 成员引用基类型"int [13]"不是结构或联合
- 成员引用基类型 'double [10]' 不是结构或联合
- std::function 中不允许引用返回类型吗?
- 了解取消引用的类型 - const_iterator
- C 有一个关键字,允许从派生类引用基本类型
- 对于实际指针类型,用于检测类似指针(可取消引用)类型的模板函数失败
- 错误:成员引用基类型"uint32_t"(也称为"无符号 INT")不是结构或联合
- 引用模板类型的赋值运算符需要非常量重载
- 模板类中引用的引用的类型是什么
- 如何在默认模板参数中引用 self 类型
- 将模板类与引用非类型模板参数一起使用时出现链接器错误
- 对"vtable for "命名空间继承的未定义引用 对"类型信息"的未定义引用
- 从具有引用返回类型的函数返回什么
- 字符串和引用返回类型 C++?