混淆C++;模板 我正在学习C++模板。有人能解释这段代码的每一点吗 template <class T> struct identity { typedef T type; }; template <class T> T&& forward(typename identity<T>::type&& a) { return a; } 模板 结构标识 { T型; }; 模板 T&&forward(类型名称标识::类型&&a) { 返回a; }

混淆C++;模板 我正在学习C++模板。有人能解释这段代码的每一点吗 template <class T> struct identity { typedef T type; }; template <class T> T&& forward(typename identity<T>::type&& a) { return a; } 模板 结构标识 { T型; }; 模板 T&&forward(类型名称标识::类型&&a) { 返回a; },c++,templates,struct,rvalue-reference,typename,C++,Templates,Struct,Rvalue Reference,Typename,首先,您需要为my_forward进行另一个专门化以允许此呼叫: int a; my_forward<int>(a); 但在这种情况下,需要 int a; my_forward<int&>(std::ref(a)); 首先,您需要对my_forward进行另一个专门化以允许此调用: int a; my_forward<int>(a); 但在这种情况下,需要 int a; my_forward<int&>(std::ref(a)

首先,您需要为
my_forward
进行另一个专门化以允许此呼叫:

int a;
my_forward<int>(a);
但在这种情况下,需要

int a;
my_forward<int&>(std::ref(a));

首先,您需要对
my_forward
进行另一个专门化以允许此调用:

int a;
my_forward<int>(a);
但在这种情况下,需要

int a;
my_forward<int&>(std::ref(a));
forward
是一个函数模板,它对
identity::type
返回的类型进行右值引用。编译器无法将
type
返回的类型(无论多么明显)推断为
T
(因为类型是a),因此必须明确指定
forward
的模板参数

右值引用语法
&&
(对于返回类型)也表示(非正式地)被称为通用引用的内容,因为类型
T
是一个模板参数。这意味着返回类型可以绑定到函数返回的右值和左值

参数类型
identity::type&
不是通用引用,因为返回的类型不是模板参数。这意味着该参数只能接受右值。这将要求我们将左值移动到参数中,以向前:

int main()
{
    int n{0};
    forward<int>(std::move(n));
}
否则,返回左值引用:

template <class T>
T& forward(typename identity<T>::type&& a)
{
    return a;
}
模板
转发(&F)(类型名称标识::类型(&a)
{
返回a;
}
forward
是一个函数模板,它对
identity::type
返回的类型进行右值引用。编译器无法将
type
返回的类型(无论多么明显)推断为
T
(因为类型是a),因此必须明确指定
forward
的模板参数

右值引用语法
&&
(对于返回类型)也表示(非正式地)被称为通用引用的内容,因为类型
T
是一个模板参数。这意味着返回类型可以绑定到函数返回的右值和左值

参数类型
identity::type&
不是通用引用,因为返回的类型不是模板参数。这意味着该参数只能接受右值。这将要求我们将左值移动到参数中,以向前:

int main()
{
    int n{0};
    forward<int>(std::move(n));
}
否则,返回左值引用:

template <class T>
T& forward(typename identity<T>::type&& a)
{
    return a;
}
模板
转发(&F)(类型名称标识::类型(&a)
{
返回a;
}


到处都是优秀的完美转发文章。@chris:想详细说明一下吗?完美的转发通常包括
forward
中的
remove\u reference
,但事实并非如此,
identity
似乎完全无用,因此产生的转发也不再完美。@syam,我有点看到该函数被命名为forward并得出结论。知道这是从哪里来的会很有趣。@chris:我的错,转发仍然是完美的(我想)。但是我仍然不明白身份的意义。。。如果在此期间没有其他人这么做,我会再挖掘一点,并尝试给出一个答案。我放弃了,在修补它之后,我觉得这段代码已经被破坏了(但我很可能是错的,我不是大师):它不允许右值引用。希望其他人能对此有所了解@Gaurav请告诉我们这是从哪里来的,这样我们至少可以知道来源是否可靠。到处都是优秀的完美转发文章。@chris:想详细说明一下吗?完美的转发通常包括
forward
中的
remove\u reference
,但事实并非如此,
identity
似乎完全无用,因此产生的转发也不再完美。@syam,我有点看到该函数被命名为forward并得出结论。知道这是从哪里来的会很有趣。@chris:我的错,转发仍然是完美的(我想)。但是我仍然不明白身份的意义。。。如果在此期间没有其他人这么做,我会再挖掘一点,并尝试给出一个答案。我放弃了,在修补它之后,我觉得这段代码已经被破坏了(但我很可能是错的,我不是大师):它不允许右值引用。希望其他人能对此有所了解@Gaurav请告诉我们这是从哪里来的,这样我们至少可以知道来源是否可靠。
std::move
在这种情况下(而不是cast)不是也有效吗?@0x499602D2,我不这么认为,因为
std::move
也只是一个cast,不是吗?是的,但我只是建议您改为编写它。@0x499602D2该标准还将
forward
move
的返回值指定为
static\u cast
。为了说明标准的作用,我认为
static\u cast
更清晰。在这种情况下
std::move
是否也会有效(而不是强制转换)?@0x499602D2,我不这么认为,因为
std::move
也只是强制转换,不是吗?是的,但我只是建议您改为编写它。@0x499602D2该标准还将
forward
move
的返回值指定为
static\u cast
。为了说明标准的作用,我认为
static\u cast
更为清晰。您还可以用一个简单的例子深入解释一下我们可以使用模板参数的地方。我正在尝试编写一个简单的通用堆栈代码,它可以接受任何数据类型、类,我想使用模板作为参数。我能写泛型类型,但不知道如何使用模板作为参数。@Gaurav我想你应该问另一个问题。但通常你会使用模板
template <class T>
T&& forward(typename identity<T>::type&& a)
{
    return std::move(a);
}
template <class T>
T& forward(typename identity<T>::type&& a)
{
    return a;
}