- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 C++ 的小问题。
在Effective Modern C++的第一页,有一个例子:
class Widget {
public:
Widget(Widget&& rhs);
};
此外,还有评论:“rhs 是左值,尽管它具有右值引用类型”。
老实说,我什么都不懂。 “rhs 是左值,但它的类型是右值引用”是什么意思?
最佳答案
请记住,这里有两件不同的事情:
一个与变量的类型有关:引用有两种类型:左值引用(&
)和右值引用(&&
)。
这决定了函数优先接受什么并且总是“显而易见的”,因为您可以从类型签名(或使用 decltype
)中读取它。
另一个是表达式的属性(或值):表达式可以是左值或右值 ( actually, it's more complicated than that... )。
此属性不会直接显示在代码中(但有一个经验法则,见下文),但您可以在重载决议中看到它的效果。特别是,
这些属性密切相关(并且在某种意义上彼此“双重”),但它们不一定彼此一致。尤其重要的是要认识到,变量 和表达式 实际上是不同的东西,因此从形式上讲,它们甚至没有可比性,“苹果对橘子”。
C++ 中有这样一条规则,即使您已将 rhs
声明为右值引用(意味着它将优先匹配作为右值的参数),在在移动构造函数 block 中,变量 rhs
本身仍将表现为左值,因此优先匹配接受左值引用的函数。
void test(Widget&&) { std::cout << "test(Widget&&): called\n"; }
void test(Widget&) { std::cout << "test(Widget&): called\n"; }
Widget::Widget(Widget&& rhs) {
// here, `rhs` is an lvalue, not an rvalue even though
// its type is declared to be an rvalue reference
// for example, this will match `test(Widget&)`
// rather than the `test(Widget&&)` overload, which may be
// a bit counter-intuitive
test(rhs);
// if you really want to match `test(Widget&&)`
// you must use `std::move` to "wrap" the variable
// so that it can be treated as an rvalue
test(std::move(rhs));
}
这样做的理由是为了防止移动构造函数中的意外移动。
一般的经验法则是:如果表达式有一个名称(即由单个命名变量组成),那么它就是一个左值。如果表达式是匿名的,那么它就是一个右值。 (正如 dyp 所指出的,这在技术上是不正确的——请参阅他的评论以获得更正式的描述。)
关于c++ - 需要 Meyers Effective C++ Widget 右值实例讲解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26962691/
Meyers Singleton 是否适用于有动态库的场景? IE。一个定义单例的库,其他人使用它,每个都在自己的编译单元中? (我想这无关紧要,但具体架构是 OS X 上带有框架的应用程序) 我正在
我已经阅读了很多关于单例的文章,它们应该在什么时候使用,什么时候不应该使用,以及如何安全地实现它们。我正在用 C++11 编写,并且遇到了 Meyer 的单例延迟初始化实现,如 this questi
是否可以使用参数定义 Meyer 的单例(如 this one)? 我知道 GOF 风格的单例(如 here )是可能的, 但我似乎无法让它与 Meyer 的单例一起工作: // ... public
Meyer 的单例类蓝图在头文件 temp.h 中声明。如果 temp.h 包含在两个单独的 .cpp 文件中,那么每个文件都有自己的蓝图,并且静态的东西对其他模块(即 *.o 或 *.cpp)不可见
到以下代码: class C { public: static C& Instance() { static C c; return c; }
假设我有一个类: class C{ int x_; int y_; public: C(int x, int y): x_(x), y_(y){} }; 然后我想从一个字符串中添加结构,它
我的代码: template class Singleton { public: static T& instance() { static T obj; re
我继承了一些在 g++ 9 和 10 下编译良好的代码,但是当打开优化时,两个编译器都会出现运行时错误(也就是说,编译 -O0 有效,但编译 -Og 会给出来自 MMU 的运行时错误.) 问题是在一个
我过来了this question最近,对 Instance() 函数的实现产生了疑问: class Configuration { public: static Configuration*
上周有人指出我有一段代码是这样的: #include namespace NSTest { class SingletonClass { public: static SingletonCl
我有以下实现基本 Meyers 单调的代码: #ifndef _cConfigFile_HH #define _cConfigFile_HH class cConfigFile { public:
Singleton(Meyers 的 Singleton)的以下使用惰性初始化的实现是否线程安全? static Singleton& instance() { static Singlet
我有一个在 Meyers 单例中运行的 boost 线程。它在我的程序期间愉快地运行。 当我的 Singleton 的析构函数被调用时(当程序加载出内存时)我设置了一个标志以便线程应该退出它的循环并触
Singleton(Meyers 的 Singleton)的以下使用惰性初始化的实现是否线程安全? static Singleton& instance() { static Singlet
我正在阅读 S. Meyers 的书“Effective C++。55 specific ways...”(第 3 版)。这本书中的某些内容,在规则 11 中,我不明白。所以,在下一个代码部分: Wi
我正在关注 Item6,它是 Scott Meyers 着的 Effective STL: 50 Specific Ways to Improve Your Use of the Standard T
我只是尝试使用 Scott Meyers 在“Effectice C++ in an Embedded Environment”中建议的 placement new 运算符。 DefaultM
我正在阅读 std::shared_ptr在Effective Modern C++14 Scott Meyers 的书。这是一段代码,作者说其中可能存在资源泄漏: int computePriori
Singleton(Meyers 的 Singleton)线程的以下使用延迟初始化的实现是否安全? static Singleton& instance() { static Singlet
所以我读了很多关于为什么这个实现不是线程安全的。但是我没有找到如何使其线程安全快速的答案?使其线程安全的变体是添加互斥体(或者在某些情况下,只需关键部分就足够了),但这会使该方法慢得多。那么是否有一种
我是一名优秀的程序员,十分优秀!