C++ 我的通用模板应该使用T还是T&&;?
我在一个文件中工作,该文件有一个给定的函数和许多重载,如下所示:C++ 我的通用模板应该使用T还是T&&;?,c++,templates,c++11,C++,Templates,C++11,我在一个文件中工作,该文件有一个给定的函数和许多重载,如下所示: inline X f(ScriptWrappable* impl, Y y, Z z) { ... } inline X f(Node* impl, Y y, Z z) { ... } inline X f(RawPtr<T> impl, Y y, Z z) { ... } inline X f(const RefPtr<T>& impl, Y y, Z z) { ... } inline X f(
inline X f(ScriptWrappable* impl, Y y, Z z) { ... }
inline X f(Node* impl, Y y, Z z) { ... }
inline X f(RawPtr<T> impl, Y y, Z z) { ... }
inline X f(const RefPtr<T>& impl, Y y, Z z) { ... }
inline X f(ScriptWrappable* impl, Y y, Z z) { ... }
inline X f(const String& impl, Y y, Z z) { ... }
inline X f(int64_t impl, Y y, Z z) { ... }
template<typename T, size_t capacity> inline X f(const Vector<T, capacity>& impl, Y y, Z z) { ... }
template<typename T> inline X f(T impl, W w) {
return f(impl, w->getY(), w->getZ());
}
我真的不知道这个问题的答案。我以为我了解通用参考文献,但我不知道它们是好主意还是坏主意。在我选择其中一个的情况下会有什么后果
如果我不得不猜测的话,我会说,由于T可以代表的原始类型都是易于复制的(原语、引用或指针),T&&不会带来太多好处。但是我仍然很好奇,例如,是否有任何类型可以传递到T&&version,而不能传递到T版本,或者反之亦然。您应该这样编写函数:
template<typename T> inline X f(T&& impl, W w) {
return f(std::forward<T>(impl), w->getY(), w->getZ());
}
模板内联X f(T&&impl,W){
返回f(std::forward(impl),w->getY(),w->getZ());
}
这就是所谓的完美转发。
impl
的类型将与您直接调用f
的类型完全相同。它不一定是r值引用。答案有点复杂,因为它需要对编译器关于模板的规则有一些了解
在以下声明中:
template<class T> void func(T&& t);
在这种情况下,foo实际上需要一个r值引用
这也不是推论的背景:
template<class T>
struct X {
void foo(T&& t);
};
template<class T>
void foo(std::vector<T>&& v);
模板
void foo(std::vector&&v);
在这两种情况下,您应该使用
std::move
如果调用方想要移动,他应该只std::move
参数。使用T&
你是在强迫他这么做。只使用T
你给了他一个选择。在推断上下文中使用模板时,这是不正确的。我不知道这一点。谢谢你的澄清。const参考似乎足够了。谢谢!听起来完美的转发更符合我的意图。我仍然希望了解如果我选择了其他替代方案,会发生什么不同,但搜索“完美转发”会给我类似的页面似乎有所帮助。看看Richard Hodges的答案。@TobiasBrandt,除非f打算拥有impl,否则为什么不使用const T&。@JohanLundbergT&
更一般。例如,如果T=int
并且存在过载f(int,Y,Z)
,则将拾取该过载。如果只有f(const int&,Y,Z)
的重载,则将选择该重载。这将选择是使用“按值传递”还是“按常量引用传递”移动到它所属的(非模板)f
的实现中。@TobiasBrandt,“这将选择…移动到它所属的…f”。这一点很清楚,我也同意。不是在推导的上下文中对t
的评估使其成为r值或l值参考<代码>类型定义int&T;typedef T&X没有推导出的上下文,但是X
的类型是int&
。替换为typedef int T
和X
成为int&
类型。在进行右值或左值引用时,不存在涉及演绎的魔法;这就是引用折叠规则。演绎规则确实会导致T&&
中的T
以某种方式被演绎,以允许所述规则生成l或r值引用,但这是一个真正的区别。如果我的措辞有误,请原谅。单词的正确形式是什么?那些可以的,发布。不能批评别人的人,批评别人的帖子。:)从函数参数和转发引用中谈论模板类型推断所需的词语选择很困难。
template<class T>
void foo(std::vector<T>&& v);