为什么通用参考被视为 R 值参考?

Why is Universal reference being treated as R-Value reference?

#include <iostream>

class A
{
public:
    A() {};
};

template <class T>
class Test
{
public:
    void func1(T&& t)
    {

    }
};

int main()
{
    A a;
    Test<A> o1;

    o1.func1(a); 

    return 0;
}

编译时出现以下错误

error C2664: 'void Test<A>::func1(T &&)': cannot convert argument 1 from 'A' to 'T &&'
note: You cannot bind an lvalue to an rvalue reference

o1是用"A"实例化模板class测试得到的。所以调用 o1.func1(a) 应该知道 void func1(T&& t) 应该解析为 void func1(A&& t)

我认为void func1(T&& t)中的T&&应该被推断为通用引用或转发引用,因为它来自模板类型参数。那为什么在上面的错误中它说 "You cannot bind an lvalue to an rvalue reference"?

我是不是漏掉了一些模板魔法?

I thought T&& in void func1(T&& t) should be deduced as a universal reference or a forwarding reference [...]

没有。 t 在您的示例中不是通用参考。要成为通用参考,它必须从调用中推导出来,但在您的示例中 T 只是 A。这是一个通用参考:

template <class T>
class Test
{
public:
    template <typename X>
    void func1(X&& t)
    {

    }
};

重要的细节被“演绎”出来了。在您的示例中,没有任何推论。考虑 Test<A> 等同于

class TestA
{
public:     
    void func1(A&& t)
    {

    }
};

一旦你实例化了class模板,它的方法func1有参数tpyeA&&,不是别的东西,即没有什么可以推导了。当您没有明确声明模板参数时,就会发生模板参数推导,如

 template <typename T> void foo(T&& t) {};
 
 foo(1);