模板重载(引用和非引用版本)

时间:2016-08-01 11:11:41

标签: c++ templates overloading

我有一个看似简单的问题,我不知道如何解决。

想象一下以下模板方法

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会在这种情况下有用吗?

2 个答案:

答案 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,则需要更新编译器,然后使用转发引用&&