1
struct X {
      X() {}
      X(X&&) { }
};
X global_m;

struct Converts {
        operator X&& () const { return std::move(global_m); }
};

我相信以下应该有效:

X x { Converts{} };

X 只有一个单参数构造函数。它需要一个X&&. Converts 对象是临时的,它转换为X&&. 那么为什么我会从 clang-3.3 收到此错误消息:

 // error: "candidate constructor not viable: no known conversion from 'Converts' to 'X &&' for 1st argument"

我能够明确地将运算符称为:

X x { Converts{}.operator struct X&& () }; // this works.

对我来说不幸的是,它适用于ideone,据我所知,它基于 g++ 。目前是否有任何在线clang编译器正在运行?

4

1 回答 1

1

根据这个答案,这是标准中的一个缺陷。这是对建议的标准@ecatmur 的更正。

4 - 但是,当考虑作为候选的构造函数或用户定义转换函数的参数时:

  • 由 13.3.1.3 [over.match.ctor] 在类复制初始化的第二步中调用以复制临时文件时,或
  • 在所有情况下,通过 13.3.1.4 [over.match.copy]、13.3.1.5 [over.match.conv] 或 13.3.1.6 [over.match.ref],

只考虑标准转换序列和省略号转换序列;当考虑作为X13.3.1.7 [over.match.list] 候选的类的构造函数的第一个参数时,当将初始化列表作为单个参数传递或初始化列表只有一个元素时,用户定义的转换仅当其用户定义的转换由转换函数指定时才考虑toX或 reference to (可能是cv限定的) 。X[注意:因为在列表初始化的上下文中,隐式转换序列中允许有多个用户定义的转换,所以这个限制是必要的,以确保X使用单个参数调用的转换构造函数athat 不是类型X或派生自 的类型,对于使用本身构造的临时对象调用X的构造函数并不模棱两可。——尾注]XXa

我不知道这是否正是标准最终被改变的方式(因为我只有一个草稿)但我认为由于结果的变化取决于编译器版本,我认为已经完成了一些事情

于 2013-11-03T22:48:14.407 回答