#include <iostream> struct D; struct S{ operator D(); }; struct D{ D(){} D(D&&) { std::cout << "move constructor" << '\n'; } }; S::operator D() { std::cout << "conversion function" << '\n'; return D(); } int main() { S s; D d(s); }
我基于以下理由对这个省略的正确性提出异议:
>这个案例在§8.5/ 16(N3337)的第一个子项目中有所涉及,它没有提及elision.
If the initialization is direct-initialization,or if it is
copy-initialization where the cv-unqualified version of the source
type is the same class as,or a derived class of,the class of the
destination,constructors are considered. The applicable constructors
are enumerated (13.3.1.3),and the best one is chosen through overload
resolution (13.3). The constructor so selected is called to initialize
the object,with the initializer expression or expression-list as its
argument(s). If no constructor applies,or the overload resolution is
ambiguous,the initialization is ill-formed.
解决方法
复制/移动省略规则在12.8 / 31中规定.您的代码中有两个要删除的复制/移动操作.
第一个很简单:在运算符D中,返回表达式中构造的临时值被移动到表示函数返回值的临时值.子弹3允许省略此举.
第二个是将临时函数返回值移动到d对象.同样,子弹3允许省略.
- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type,the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move