我有一个看似简单的问题,我不知道如何解决。
想象一下以下模板方法
template<typename T> void Add(T& var);
其中专业化可以向容器添加内容(排序)。我可以传递POD
或更复杂的类型,例如strings
,这就是我将T作为参考传递的原因。
这个问题是,无论什么时候我想用另一种方法调用Add(...),如:
Add(MethodThatReturnsAnInt());
这不会起作用,需要一个临时变量来保存MethodThatReturnsAnInt()
的结果。
是否有任何方法可以重载Add
以便我可以使用引用传递和非引用传递版本?
template<typename T> void Add(T& var);
template<typename T> void Add(T var);
std::enable_if
会在这种情况下有用吗?
答案 0 :(得分:6)
如果你有一个C ++ 11编译器,你可以使用 (Universal Reference) 转发参考:
template<typename T> void Add(T&& var) {}
int MethodThatReturnsAnInt() { return 42; }
int main()
{
int a = MethodThatReturnsAnInt();
Add(a); // lvalue passed: void Add(int& var) takes lvalue reference
Add(MethodThatReturnsAnInt()); // rvalue passed: void Add(int&& var) takes rvalue reference
}
在此示例中, T&&
不是右值引用。在类型推导上下文T&&
具有特殊含义。 T
取决于传递给函数Add()
的表达式,如下所示:
如果表达式为a
类型的左值(例如:E
),则T推导为E&
。
如果表达式是 rvalue (例如:函数返回的值)E
类型,则T推导为E
和{{1将具有类型var
。
答案 1 :(得分:2)
如果您的编译器不支持C ++ 11,则需要更新编译器,然后使用转发引用&&
。