根据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)是类模板成员;它不是独立的功能模板。这是否违反了我上面提到的转发参考定义?
谢谢!
因为
f(T&& x)
接受左值和右值引用
不是。您这里没有比较the same成员函数。 MyClass<int&>::f
是一个仅接受左值的类的成员函数。同时MyClass<int&&>::f
是another类的成员函数,并且仅接受右值。
类模板不是类。这是一个用来制作类的小甜饼。尽管该专业化具有类似命名的成员函数,但它们在不同类中仍是不同的函数。
如果您尝试传递MyClass<int&>::f
一个右值,您的代码将无法成功构建,
myClass1.f(10); // ERROR
关于转发引用的事情是,它们在模板参数推导过程中自动成为右值引用或左值引用。呼叫者不需要指定他们想要的。
在您的示例中,您已明确指定int&
和int&&
,这将强制f
具有一种类型或另一种类型。然后,它相应地采用左值或右值,但两者都不像转发引用可以那样:myClass1.f(10);
和myClass2.f(i);
都格式不正确。