c++ - 为什么这个类模板参数被视为转发引用?
问题描述
根据https://en.cppreference.com/w/cpp/language/reference,转发引用是,
- 声明为右值引用的函数模板的函数参数。
- 汽车&&。
在https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers Scott Meyers 解释说,虽然 vector::push_back(T&& x) 需要一个 T&&,但它不是通用的参考。这只是一个普通的右值引用。
但是,我下面的代码编译并运行良好:
#include <iostream>
template<typename T>
class MyClass
{
public:
void f(T&& x)
{
std::cout << __FUNCSIG__ << std::endl;
}
};
int main()
{
int i = 10;
MyClass<int&> myClass1;
myClass1.f(i); //void __thiscall MyClass<int &>::f(int &)
MyClass<int&&> myClass2;
myClass2.f(10); //void __thiscall MyClass<int &&>::f(int &&)
}
听起来 T&& 在这里被视为转发引用,因为 f(T&& x) 接受左值和右值引用。但是 f(T&& x) 是类模板成员;它不是一个独立的函数模板。这是否违反我上面提到的转发参考定义?
<<\添加-->
在函数模板中转发引用的情况下,函数模板本身也需要基于特定类型 T 进行实例化。我们可以显式地表达这一点:
template<class T>
void f(T&& x)
{}
int main() {
int i = 10;
f<int&>(i); // argument is lvalue
f<int&&>(10); // argument is rvalue
}
f<\int&> 和 f<\int&&> 是上述函数模板的两个不同实例。它们也不是在幕后指向相同的函数地址,类似于类模板实例化。当然,我们需要类对象来使用它的功能。
<--结束添加>
解决方案
因为
f(T&& x)
接受左值和右值引用
它没有。您在这里没有比较相同的成员函数。MyClass<int&>::f
是一个只接受左值的类的成员函数。同时MyClass<int&&>::f
是另一个类的成员函数,它只接受右值。
类模板不是类。这是一个千篇一律的制作类的工具。尽管特化具有类似命名的成员函数,但它们仍然是不同类中的不同函数。
如果您尝试传递MyClass<int&>::f
右值,您的代码将无法成功构建,
myClass1.f(10); // ERROR
引用折叠使生成f
的 ' 接受不同值类别的引用,但是一旦类被实例化,该成员将只接受特定的值类别。它不像转发引用那样转发在调用站点推导出的值类别。
推荐阅读
- regex - 以括号结尾的句子的标题案例
- c++ - 当条件为真时如何重复 do-while 循环
- git - 从发布(CD)管道触发构建(CI)管道?
- css - 如何将引导程序 4 卡体类划分为 2 列
- c# - 从数字中删除指定的 60 倍数?
- firebase-analytics - user_pseudo_id 更改而无需重新安装应用程序
- java - 我无法显示另一个包中的 ArrayList 中的对象
- api - (Wso2 Api Manager 2.6.0)如何使用调解器发送字符串列表作为输入?
- node.js - 页面加载时的 Graphql 错误请求
- amazon-web-services - 如何将快照还原到现有的 Aurora 数据库实例?