通用引用模板类型总是评估为左值

Universal reference template type always evaluate to lvalue

我的代码:

#include <string>
#include <utility>
#include <iostream>

void store(std::string & val)
{
    std::cout << "lvalue " << val << '\n';
}

void store(std::string && val)
{
    std::cout << "rvalue " << val << '\n';
}

template<typename T> void print(T && val)
{
    std::cout << std::boolalpha << std::is_lvalue_reference<T>::value << " ";
    store(std::forward<T>(val));
}

int main()
{
    std::string val("something");
    print(val);
    print("something else");
}

我的输出:

true lvalue something
true rvalue something else

我已经阅读了通用引用并理解为什么当输入是左值时 T 是左值,但我不明白当输入是右值时 T 为什么是左值,它如何向右折叠参数?

问题不在于转发参考。这是因为您没有将 std::string 右值传递给函数。

您正在传递一个长度为 15 个字符的字符串文字,其类型为 const char[15]。并且字符串文字是不可修改的左值,因此引用被推导为 const char (&)[15].

您看到右值重载打印的原因是,好吧,您可以从字符数组构造一个临时 std::string

I don't understand how is T a lvalue when the input is a rvalue, how does that collapse to the right paramter?

不,输入不是右值。

字符串文字是左值,这就是您作为参数传递给函数的内容。这就是打印 "true" 的原因。

现在回想一下,字符串文字无法修改 (String Literals)。

因此,"something else" 的长度为 14 + 1(对于空终止符),因此 const char[15].

现在,由于无法修改字符串文字,因此引用将推导为:

 const char(&)[15];

你的方法原型是:

store(std::string && val)

const char.

创建一个临时的 std::string