gpt4 book ai didi

c++ - 通过用户定义的转换复制类类型的初始化

转载 作者:太空狗 更新时间:2023-10-29 21:45:01 26 4
gpt4 key购买 nike

我有以下代码片段:

struct T {
T(const T&) = default;
T(const S &);
};

struct S {
operator T();
};

int main() {
S s;
T t = s; // copy-initialization of class type
return 0;
}

我的问题是为什么编译器更喜欢 S::operator T() 来初始化 t 而不是报告初始化不明确的错误。在我看来会发生以下情况(如果我错了请纠正我):

  • t 是用类型 S 的左值复制初始化的
  • S 不是 T,S 也不是 T 的子类,所以 S 和 T 不相关
  • 由于变量 t 是复制初始化的,而且类型 S 和 T 不相关,编译器会尝试找到用户定义的转换序列来进行初始化。
  • 重载决策负责选择最佳的用户定义转换,它可以是 T 的转换构造函数或 S 的转换函数
  • 来自参数 s 的构造函数 T::T(const S&) 的隐式转换序列是恒等转换,因为左值 s 可以直接绑定(bind)到此左值引用
  • 对于参数s的转换函数S::operator T()的隐式转换序列也是恒等转换,因为隐式对象参数是S&

构造函数和转换函数都返回类型为 T 的纯右值,可用于直接初始化变量 t。这意味着两个用户自定义转换序列的第二个标准转换序列是恒等转换。

这意味着两个用户定义的转换序列同样好。还是有一个特殊的规则更喜欢转换函数?

我正在阅读 c++11 标准中的以下规则:

The initialization that occurs in the form T x = a; as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization.

The semantics of initializers are as follows...If the destination type is a (possibly cv-qualified) class type: 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.... Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3)

User-defined conversion sequence U1 is a better conversion sequence than another user defined conversion sequence U2 if they contain the same user-defined conversion function or constructor and if the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2

也许我在做错误的假设。我希望你能帮助我!

最佳答案

使用转换运算符从 S 转换比使用 S const 作为参数转换为 T 更好。如果您使 s 成为 S const,则首选构造函数:您的身份操作在一种情况下确实是身份操作,在其他情况不是。如果将 S 的转换运算符设为 const 成员,就会出现歧义。以下是演示所有情况的测试程序:

struct S;
struct T {
T(const T&) = default;
T(const S &);
};

struct S {
S(); // needed to allow creation of a const object
#ifdef AMBIGUOUS
operator T() const;
#else
operator T();
#endif
};

int main() {
#ifdef CONST
S const s;
#else
S s;
#endif
T t = s; // copy-initialization of class type
return 0;
}

关于c++ - 通过用户定义的转换复制类类型的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18625172/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com