模板中rvalue引用和const左值引用之间的重载

时间:2015-01-08 08:38:04

标签: c++ templates c++11 rvalue-reference

我想基于参数是否是临时对象来重载两个函数,所以我写这样的代码:

#include <iostream>

void f(int &&)
{
  std::cout << "&&" << std::endl;
}

void f(const int&)
{
  std::cout << "const &" << std::endl;
}

int main()
{
  int i;
  f(i);
  f(i + 1);
}

它正确地输出:

const &
&&

但是,当我将代码更改为使用这样的模板时:

#include <iostream>

template <typename T>
void f(T &&)
{
  std::cout << "&&" << std::endl;
}

template <typename T>
void f(const T&)
{
  std::cout << "const &" << std::endl;
}

int main()
{
  int i;
  f(i);
  f(i + 1);
}

输出变为:

&&
&&

问题是什么?如何在使用模板时优化可移动临时对象?

编辑:

实际上,当我阅读C ++ Primer时,这是一个测试代码。它说:

template <typename T> void f(T&&);       // binds to nonconst rvalues
template <typename T> void f(const T&);  // lvalues and const rvalues

在我的实验之后,这本书似乎在这里犯了错误。

1 个答案:

答案 0 :(得分:1)

template <typename T>
void f(T &&)
{
  std::cout << "&&" << std::endl;
}

使用 通用转发参考,并允许任何带参考折叠的类型。

您必须使用T并且不使用推导上下文将代码包装到结构中:

template <typename T>
struct helper
{

    void f(T &&)
    {
      std::cout << "&&" << std::endl;
    }

    void f(const T&)
    {
      std::cout << "const &" << std::endl;
    }

};

template <typename T>
void f(T &&t)
{
     helper<typename std::decay<T>::type>().f(std::forward<T>(t));
}

Live example