【发布时间】:2016-05-27 11:40:01
【问题描述】:
我最近在某处(不记得在哪里)读到关于使用大括号来允许多个用户定义的转换,但是我不明白的构造函数转换和转换方法转换之间似乎存在差异。
考虑:
#include <string>
using ::std::string;
struct C {
C() {}
};
struct A {
A(const string& s) {} // Make std::string convertible to A.
operator C() const { return C(); } // Makes A convertible to C.
};
struct B {
B() {}
B(const A& a) {} // Makes A convertible to B.
};
int main() {
B b;
C c;
// This works.
// Conversion chain (all thru ctors): char* -> string -> A -> B
b = {{"char *"}};
// These two attempts to make the final conversion through A's
// conversion method yield compiler errors.
c = {{"char *"}};
c = {{{"char *"}}};
// On the other hand, this does work (not surprisingly).
c = A{"char *"};
}
现在,我可能误解了编译器在做什么,但是(基于上述和其他实验)在我看来,它没有考虑通过转换方法进行转换。但是,通读标准的第 4 节和第 13.3.3.1 节,我无法找到原因。有什么解释?
更新
我想解释另一个有趣的现象。如果我添加
struct D {
void operator<<(const B& b) {}
};
在main:
D d;
d << {{ "char *" }};
我得到一个错误,但如果我写 d.operator<<({{ "char *" }}); 它工作正常。
更新 2
看起来标准中的第 8.5.4 节可能有一些答案。我会报告我的发现。
【问题讨论】:
-
初始化使用构造函数,并且不会使用中间类型的转换运算符。这两个非工作示例失败了,因为隐式构造
A以使用其operator C违背了这一点。 -
彼得,我想了解的是规则到底是什么。如果我写
c = A{...或c = {A{...它可以通过转换方法正常工作。如果我放弃A,为什么它决定只使用ctors? -
我希望你知道在任何代码中包含任何一个月内不会被放弃的东西是一个相当糟糕的主意。知道编译器在做什么总是比让它发狂要好。
-
嗯什么。为什么您希望 C 隐式转换为不相关的类 A?
标签: c++ c++11 implicit-conversion list-initialization