为什么将此类模板参数视为转发参考?

问题描述 投票:0回答:2

根据https://en.cppreference.com/w/cpp/language/reference,转发引用是,

  1. 声明为右值引用的功能模板的功能参数。
  2. 自动&&。

此处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)是类模板成员;它不是独立的功能模板。这是否违反了我上面提到的转发参考定义?

谢谢!

c++ rvalue-reference type-deduction forwarding-reference
2个回答
1
投票

因为f(T&& x)接受左值和右值引用

不是。您这里没有比较the same成员函数。 MyClass<int&>::f是一个仅接受左值的类的成员函数。同时MyClass<int&&>::fanother类的成员函数,并且仅接受右值。

类模板不是类。这是一个用来制作类的小甜饼。尽管该专业化具有类似命名的成员函数,但它们在不同类中仍是不同的函数。

如果您尝试传递MyClass<int&>::f一个右值,您的代码将无法成功构建,

myClass1.f(10); // ERROR

0
投票

关于转发引用的事情是,它们在模板参数推导过程中自动成为右值引用或左值引用。呼叫者不需要指定他们想要的。

在您的示例中,您已明确指定int&int&&,这将强制f具有一种类型或另一种类型。然后,它相应地采用左值或右值,但两者都不像转发引用可以那样:myClass1.f(10);myClass2.f(i);都格式不正确。

© www.soinside.com 2019 - 2024. All rights reserved.