c++ - 何时使用具有静态存储持续时间的右值引用?

标签 c++ c++11

C++11 允许在全局(、命名空间、类)范围内声明右值引用并具有静态存储持续时间。使用此类变量的最佳方案是什么?我做了几次测试,并提出了一些意见。以下代码将编译(g++ 5.3)

double&& m = 3.5;
double&& s() {return m;}

testy.cpp: In function ‘double&& s()’:

testy.cpp:7:22: error: cannot bind ‘double’ lvalue to ‘double&&’ double&& s() {return l;}

这是相当违反直觉的,即使我们声明了一个右值引用,它也被视为数据是按值返回的。当然,这是一个人为的例子,实际上返回右值引用是很少见的。 但是为什么它不起作用?我的解释是,通过声明具有静态存储持续时间的右值引用 m,我们得到了一种“通用引用”的形式,这是 Scott 创造的一个术语迈耶斯(更多信息 here )。通用引用的一个属性是它可以绑定(bind)到左值和右值。然而,与依赖于类型替换导致的引用崩溃的“通用引用”不同,我不清楚上述解决方案中涉及的机制。事实上,下面的代码编译没有问题。

double&& m = 3.5;

int main() {
    double a {4.2};
    double& b = a;
    m = a;
    m = b;
    m = 3.2;
}

因此,如上所述,m 绑定(bind)到 double 的每一种口味。然而,变量具有静态存储持续时间的事实似乎与绑定(bind)到临时对象的右值的性质相矛盾。出现的问题很少。 为什么允许这样做?什么场景会使用这个属性?。我的第一个猜测是我们可以使用它来提供接受任何参数“ flavor ”的模板特化,就像通用引用一样,除了它们与底层类型的绑定(bind)更牢固。此外,“静态右值引用”的范围似乎无关紧要,即具有静态存储持续时间和“函数”范围的右值也表现出如下所示的行为。

int main() {
    static double&& a = 4.2;
    double b = 3.2;
    double& c = b;
    a = b;
    a = c;
}

最佳答案

无法编译的原因在错误信息中:

testy.cpp:7:22: error: cannot bind ‘double’ lvalue to ‘double&&’ double&& s() {return l;}

命名变量总是左值——l 是一个左值。 s() 返回一个右值。您必须使用强制转换才能完成这项工作:

double&& s() {return std::move(m); }

Why is that allowed? What scenario will make use of this property?

是否真的值得为明确禁止它的语言添加异常(exception)?

关于c++ - 何时使用具有静态存储持续时间的右值引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36085923/

相关文章:

c++ - constexpr 和未定义的行为

c++ - 我可以使用 std::shared_ptr 而不是 boost::shared_ptr 构建 boost 库吗

c++11 - 在 C++ 中, "enum class"与 "enum"之间的内存使用情况是否存在差异?

c++ - 是否有 decltype 的快捷方式

c++ - open62541:引用函数的链接器工具错误

c++ - Stringstream 没有按需要阅读

c++ - 从派生类访问基类中的类型别名

c++ - 在 QT C++ 中为行或列添加右键单击并添加复制选项

c++ - 我不明白这个链接错误

c++ - 从具有一个分配器的 vector 移动到具有另一个分配器的 vector