通用引用模板类型总是计算为左值

Posted

技术标签:

【中文标题】通用引用模板类型总是计算为左值【英文标题】:Universal reference template type always evaluate to lvalue 【发布时间】:2017-09-18 06:48:57 【问题描述】:

我的代码:

#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 是左值如何折叠到正确的参数?

【问题讨论】:

字符串文字是左值。 @T.C 对,谢谢...愚蠢的错误 【参考方案1】:

我不明白当输入是右值时,T 是如何成为左值的,它如何折叠到正确的参数?

不,输入不是右值。

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

现在,请记住 字符串文字不能修改 (String Literals)。

因此,“其他东西”的长度为 14 + 1(对于空终止符),因此是 const char[15]

现在,由于字符串文字不能被修改,引用将被推断为:

 const char(&)[15];

你方法的原型是:

store(std::string && val)

const char 创建一个临时的std::string

【讨论】:

【参考方案2】:

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

您正在传递一个长度为 15 个字符的字符串文字,其类型为 const char[15]。并且字符串字面量是不可修改的左值,所以引用推断为const char (&amp;)[15]

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

【讨论】:

不错的答案,我发布了一个,但你快了 36 秒,所以 +1!但是我不明白你的第一句话……除此之外,我们似乎同意! :D @gsamaras - 谢谢。我的第一句话是关于 OP 的标题。他们假设引用在不应该的情况下推断为左值。

以上是关于通用引用模板类型总是计算为左值的主要内容,如果未能解决你的问题,请参考以下文章

“非常量引用的初始值必须为左值“及“匿名对象“

完美转发

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断和引用

c++模板的引用类型参数折叠问题解释

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

非常量引用的初始值必须为左值的问题