C ++ 03中的完美转发

时间:2010-08-28 18:00:23

标签: c++ forwarding c++03

如果你有这个功能

template<typename T> f(T&);

然后尝试调用它,让我们说一个像

这样的右值
f(1);

为什么不将T推导为const int,使参数成为const int&amp;因此可绑定到右值?

2 个答案:

答案 0 :(得分:22)

我在the document中链接的recent C++0x forwarding question中提到了这个可能的解决方案。

工作得相当好,但它破坏了现有的代码。考虑(直接来自文档):

template<class A1> void f(A1 & a1)
{
    std::cout << 1 << std::endl;
}

void f(long const &)
{
    std::cout << 2 << std::endl;
}

int main()
{
    f(5);              // prints 2 under the current rules, 1 after the change
    int const n(5);
    f(n);              // 1 in both cases
}

或者

// helper function in a header

template<class T> void something(T & t) // #1
{
    t.something();
}

// source

#include <vector>

void something(bool) // #2
{
}

int main()
{
    std::vector<bool> v(5);

    // resolves to #2 under the current rules, #1 after the change
    something(v[0]);
}

这也无法转发值类别(左值或右值),这在C ++ 03中没有太大问题。但由于此修复只能在C ++ 0x期间完成,因此我们在转发时会有效地将自己从rvalue引用中关闭(这是一件坏事)。我们应该努力寻求更好的解决方案。

答案 1 :(得分:1)

确实如此,但只有当您宣布fT const &时才会这样做。

template <typename T> void f(T &);
template <typename T> void g(T const &);

void x() { f(1); }  // error: invalid initialization of non-const reference
void y() { g(1); }  // no error

如果您声明 f(T &)f(T const &),它将选择符合const的条件:

template <typename T> void f(T &);
template <typename T> void f(T const &);

void x() { f(1); } // no error, calls f(T const &)

现在也许你说“在第一个例子中,当 生成一个int时,为什么它会为f的调用生成一个const int类型的临时值临时类型{{1}}并使代码编译?“我得到的最佳答案是,当参数不是整数常量时,这与重载解析行为不一致。