在下面的代码中,我不允许声明一个显式的 ctor,因为编译器说我在复制初始化上下文中使用它(clang 3.3和gcc 4.8).我试图通过使ctor非显式,然后将复制构造函数声明为已删除来证明编译器是错误的.
编译器是错误还是有其他解释?
#includetemplate struct xyz { constexpr xyz (xyz const &) = delete; constexpr xyz (xyz &&) = delete; xyz & operator = (xyz const &) = delete; xyz & operator = (xyz &&) = delete; T i; /*explicit*/ constexpr xyz (T i): i(i) { } }; template xyz make_xyz (T && i) { return {std::forward (i)}; } int main () { //auto && x = make_xyz(7); auto && x (make_xyz(7)); // compiler sees copy-initialization here too std::cout << x.i << std::endl; }
更新一个不切实际但更简单的版本
struct xyz { constexpr xyz (xyz const &) = delete; constexpr xyz (xyz &&) = delete; xyz & operator = (xyz const &) = delete; xyz & operator = (xyz &&) = delete; int i; explicit constexpr xyz (int i): i(i) { } }; xyz make_xyz (int && i) { return {i}; } int main () { xyz && x = make_xyz(7); }
Potatoswatte.. 7
的=
,因为参考绑定不不同的表现是否通过指示按或复制初始化表示标记应不影响投诉.这里初始化的是返回值对象,它没有自己的名称.
不幸的是,GCC和Clang一样抱怨是对的.根据§6.6.3/ 2 [stmt.return],
带有braced-init-list的return语句通过copy-list-initialization(8.5.4)从指定的初始化列表初始化要从函数返回的对象或引用.
所以,那里有一个看不见的=
标志,你无法绕过它.