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

Overload between rvalue reference and const lvalue reference in template

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

#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

经过我的实验,书上好像写错了。

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