11

谁能解释一下为什么会编译以及为什么会t以 type 结尾int&

#include <utility>

void f(int& r)
{
    ++r;
}

template <typename Fun, typename T>
void g(Fun fun, T&& t) 
{ 
    fun(std::forward<T>(t)); 
}

int main()
{
    int i = 0;

    g(f, i);
}

我在 GCC 4.5.0 20100604 和 GDB 7.2-60.2 上看到了这个

4

2 回答 2

17

由于完美转发,当参数 toP&&是一个左值时, thenP将被推断为参数的类型加上&附加。所以你得到int & &&P存在int&。如果参数是一个右值,那么P将只推导出参数的类型,所以如果你通过,例如直接传递,你得到一个int&&参数。Pint0

int& &&将折叠到int&(这是一个语义视图 - 语法上int& &&是非法的。但是说什么U &&时候U是模板参数或 typedef 引用类型int&,那么U&&仍然是类型int&- 即两个引用“折叠”到一个左值引用)。这就是为什么t有 type int&

于 2010-12-01T18:34:51.467 回答
3

如果出于某种原因您真的想专门绑定到左值或右值,请使用元编程:

#include <type_traits>

template <typename T>
typename std::enable_if<std::is_lvalue_reference<T&&>::value, void>::type
fun(T&& x)
{
    std::cout << "lvalue argument\n";
}

template <typename T>
typename std::enable_if<std::is_rvalue_reference<T&&>::value, void>::type
fun(T&& x)
{
    std::cout << "rvalue argument\n";
}

int main()
{
    int i = 42;
    fun(i);
    fun(42);
}
于 2010-12-01T21:57:00.227 回答