【发布时间】:2015-01-08 08:38:04
【问题描述】:
我想根据参数是否为临时对象来重载两个函数,所以我写了这样的代码:
#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
经过我的实验,这本书似乎在这里犯了一个错误。
【问题讨论】:
-
“如何在使用模板时优化可移动临时对象”是什么意思?
T&&本身是最佳的,因为它绑定到所有内容并允许您恢复用作参数的表达式的值类别 -
@PiotrS。例如,如果它将变量 i 绑定到 const T&,并将表达式 i + 1 绑定到 T&&,那么我可以从 i + 1 生成的临时对象中移动资源。
-
这就是为什么有条件移动,即
std::forward<T>,取决于为T推导出的类型,它要么移动,要么根本不移动。您不必为右值显式使用std::move。请注意T&&其中T是一个类型模板参数是一个转发引用,其行为不同于常规右值引用 -
@PiotrS。当我对函数参数使用右值引用时,我希望这个参数总是绑定到临时对象。但在这种情况下,它也绑定到变量。
-
T&&withT是一个类型模板参数是一个转发引用,而不是一个右值引用,阳光下的一切都可以受转发参考约束
标签: c++ templates c++11 rvalue-reference