混淆c++模板
Confusing C++ Template
我正在学习c++模板。谁能解释一下这段代码的每一点
template <class T>
struct identity
{
typedef T type;
};
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
template <class T>
struct identity
{
typedef T type;
};
这部分定义了一个名为identity
的类模板,它包含一个名为type
的公共成员typedef
,该成员的类型是您作为模板参数传递的类型。在您的示例中,没有部分或显式专门化,因此传递给identity
的任何类型都是type
。
template <class T>
T&& forward(typename identity<T>::type&& a)
{
return a;
}
forward
是一个函数模板,接受对identity<T>::type
返回类型的右值引用。type
返回的类型(无论多么明显)不能被编译器推断为T
(因为该类型是依赖类型),因此必须显式指定forward
的模板参数。
右值引用语法&&
(用于返回类型)还表示(非正式地)称为通用引用,因为类型T
是模板参数。这意味着返回类型可以绑定到函数返回的左值和右值。
形参类型identity<T>::type&&
是而不是通用引用,因为返回的类型不是模板形参。这意味着参数只能接受右值。这就要求我们将move
的左值输入到参数forward
:
int main()
{
int n{0};
forward<int>(std::move(n));
}
最后将形参a
返回给右值引用。但是请注意,将参数返回给T&&
将不起作用,因为a
必须被移动:
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;
}
首先,您需要my_forward
的另一个专门化来允许这个调用:
int a;
my_forward<int>(a);
因此,对my_forward
的引用进行专门化:
template <class T>
T&& my_forward(typename identity<T>::type& a)
{
return static_cast<T&&>(a);
}
但是在这种情况下,调用
int a;
my_forward<int&>(std::ref(a));
是模棱两可的:
note: candidate function [with T = int &]
T&& my_forward(typename identity<T>::type&& a)
^
note: candidate function [with T = int &]
T&& my_forward(typename identity<T>::type& a)
^
为了避免它,你应该使用std::remove_reference
而不是仅仅使用identity
:
template <class T>
T&& my_forward(typename std::remove_reference<T>::type&& a)
{
return static_cast<T&&>(a);
}
template <class T>
T&& my_forward(typename std::remove_reference<T>::type& a)
{
return static_cast<T&&>(a);
}
相关文章:
- .cpp和.h文件中的模板专用化声明
- C++模板来检查友元函数的存在
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何在c++中为模板函数实例创建快捷方式
- 使用C++中的模板和运算符重载执行矩阵运算
- 有人能分解一下这个c++模板的语法吗
- 如何在c++17中制作一个模板包装器/装饰器
- 模板化建造师专业化
- 调用专用模板时出错"no matching function for call to [...]"
- 模板元程序查找相似的连续类型名称
- 如何在C++20中创建模板别名的推导指南
- 没有名称的C++模板参数
- 具有重复类型的C++可变模板
- 如何将enable-if与模板参数和参数包一起使用
- 没有用于初始化C++中的变量模板的匹配构造函数