c – 为什么没有为给定的转换 *** 作符调用构造函数?

c – 为什么没有为给定的转换 *** 作符调用构造函数?,第1张

概述struct A {}; struct B{ B (A* pA) {} B& operator = (A* pA) { return *this; }};template<typename T>struct Wrap{ T *x; operator T* () { return x; }};int main (){ Wrap<A> a; B oB =
struct A {}; struct B{  B (A* pA) {}  B& operator = (A* pA) { return *this; }};template<typename T>struct Wrap{  T *x;   operator T* () { return x; }};int main (){  Wrap<A> a;  B oB = a; // error: conversion from ‘Wrap<A>’ to non-scalar type ‘B’ requested  oB = a;  // ok}

构造oB时,为Wrap< T> ::运算符T()调用为什么B :: B(A *)? [注意:在下一个语句中为Wrap< T> :: operator T()调用B :: operator =(A *)]

解决方法 问题在于,隐式调用的用户定义转换的数量受标准限制(为1).
B ob = a;

意味着两次用户转换:

> on a:Wrap< A> ::运算符A *()应该被调用
>结果:应该调用B :: B(A *)

@James Kanze的解释:这种语法称为“复制初始化”,实际上相当于B ob = B(a)(大部分时间都复制了副本).这与B ob(a)不同,后者是“直接初始化”并且可以工作.

如果您明确限定任何一项,它将起作用,例如:

B ob = B(a);

另一方面,对于第二种情况,没有问题:

ob = a;

是短手:

ob.operator=(a);

因此,只允许进行一次用户定义的转换.

编辑:

由于评论中需要(对基里尔的答案),我们可以猜测一下动机.

链式转换可能很长很长,因此:

>可能会让用户感到惊讶 – 隐含的转换可能已经令人惊讶,因为它……
>可以导致指数搜索可能性(对于编译器) – 它需要从两端开始,尝试检查所有可能的转换,并以某种方式“加入”两者(尽可能使用最短路径).

此外,只要转换次数超过1次,您就会遇到必须检测到周期的风险(即使可能不需要诊断,并且要遵守实施质量).

所以,因为有必要限制以避免无限长的搜索(它可能没有指定,只需要最少),并且因为超过1我们可能有新的问题(周期),那么1似乎是一个很好的限制,毕竟.

总结

以上是内存溢出为你收集整理的c – 为什么没有为给定的转换 *** 作符调用构造函数?全部内容,希望文章能够帮你解决c – 为什么没有为给定的转换 *** 作符调用构造函数?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1237136.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存