- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在这里阅读一些关于转换运算符和构造函数的问题让我想到了它们之间的交互,即当存在“模糊”调用时。考虑以下代码:
class A;
class B {
public:
B(){}
B(const A&) //conversion constructor
{
cout << "called B's conversion constructor" << endl;
}
};
class A {
public:
operator B() //conversion operator
{
cout << "called A's conversion operator" << endl;
return B();
}
};
int main()
{
B b = A(); //what should be called here? apparently, A::operator B()
return 0;
}
上面的代码显示“调用A的转换运算符”,意思是调用转换运算符而不是构造函数。如果您从 A
中删除/注释掉 operator B()
代码,编译器将愉快地转而使用构造函数(无需对代码进行其他更改)。
我的问题是:
B b = A();
是一个模棱两可的调用,因此这里必须存在某种优先级。这个优先级究竟是在哪里建立的? (来自 C++ 标准的引用/引用将不胜感激)A
对象应该如何成为B
对象、A
或B
?根据 C++,答案是 A
——在面向对象的实践中是否有任何东西表明应该是这种情况?就我个人而言,无论哪种方式都有意义,所以我很想知道是如何做出选择的。提前致谢
最佳答案
您进行复制初始化,并且考虑在转换序列中进行转换的候选函数是转换函数和转换构造函数。这些是你的情况
B(const A&)
operator B()
现在,这就是您声明它们的方式。重载解决方案从中抽象出来,并将每个候选者转换为与调用参数相对应的参数列表。参数是
B(const A&)
B(A&)
第二个是因为转换函数是成员函数。 A&
是所谓的隐式对象参数,当候选者是成员函数时生成。现在,参数的类型为 A
。绑定(bind)隐式对象参数时,非常量引用可以绑定(bind)到右值。因此,另一条规则说,当您有两个参数为引用的可行函数时,具有 fewest const 资格的候选人将获胜。这就是您的转换功能获胜的原因。尝试使 operator B
成为 const 成员函数。你会注意到一个模棱两可的地方。
From an object-oriented philosophical standpoint, is this the way the code should behave? Who knows more about how an A object should become a B object, A or B? According to C++, the answer is A -- is there anything in object-oriented practice that suggests this should be the case? To me personally, it would make sense either way, so I'm interested to know how the choice was made.
郑重声明,如果你把转换函数设为const成员函数,那么GCC会选择构造函数(所以GCC似乎认为B
与它有更多的业务往来?)。切换到迂腐模式(-pedantic
)以使其引起诊断。
标准,8.5/14
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).
和13.3.1.4
Overload resolution is used to select the user-defined conversion to be invoked. Assuming that "cv1 T" is the type of the object being initialized, with T a class type, the candidate functions are selected as follows:
- The converting constructors (12.3.1) of T are candidate functions.
- When the type of the initializer expression is a class type "cv S", the conversion functions of S and its base classes are considered. Those that are not hidden within S and yield a type whose cv-unqualified version is the same type as T or is a derived class thereof are candidate functions. Conversion functions that return "reference to X" return lvalues of type X and are therefore considered to yield X for this process of selecting candidate functions.
In both cases, the argument list has one argument, which is the initializer expression. [Note: this argument will be compared against the first parameter of the constructors and against the implicit object parameter of the conversion functions. ]
还有13.3.3.2/3
- Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if [...] S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers.
关于c++ - 转换构造函数与转换运算符 : precedence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1384007/
我在犹豫要不要写preceding或 preceding-sibling在 XSL 中,例如下面的示例 xml。 Sato Tanaka Ueda
这句话相当于什么? if(cond1 AND cond2 AND cond3 OR cond4 AND cond5 AND cond6) 是吗 if((cond1 AND cond2 AND cond
在 Curry tutorial (pdf) 的第 3.5.6 节中,建议我们使用默认规则“搜索失败后重新获得控制权”。下面给出一个例子。 (为了清楚起见,我添加了类型签名并对输入进行柯里化(Curr
在 Curry tutorial (pdf) 的第 3.5.6 节中,建议我们使用默认规则“搜索失败后重新获得控制权”。下面给出一个例子。 (为了清楚起见,我添加了类型签名并对输入进行柯里化(Curr
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
一个字段有两个验证注解 @NotEmpty @Length(min=3,max=100) String firstName; 观察 如果该字段为空,则结果违规的顺序会有所不同: 有时首先违反 @Not
在这里阅读一些关于转换运算符和构造函数的问题让我想到了它们之间的交互,即当存在“模糊”调用时。考虑以下代码: class A; class B { public: B()
假设我有以下用于简单计算器语言的上下文无关语法: S->TS' S'->OP1 TE'|e T->FT' T'->OP2 FT'|e F->id|(S) OP1->+|- OP2->*|/ 可以看出
我试图点击第一个按钮删除第二个按钮的项目。 XPath //button[contains(.,'$
根据wiki AND 的优先级高于 OR。 我想知道,是否有一个子句表述为a || b && c 首先应该如何计算? (a||b)还是(b && c)? 最佳答案 由于优先级,它的计算结果为 (a |
我正在使用 jison(与 Bison 等效的 javascript)并且遇到以下优先级问题。我将使用计算器演示来说明它 http://zaach.github.com/jison/try/ 它按原样
我一直在尝试创建我的第一个便利初始化器。我收到此错误: 我收到错误:参数“valueInDollars”必须先于参数“serialNumber” 这是我的所有代码,我的问题在代码的底部,但我认为显示所
编写一些 css hack,为 :hover {} 设计样式很有趣,但浏览器会处理 a:hover完整链接 VS 哈希标签不同。 来自 http://inqdrops.com/welcom/ a, a
printf("%d", 7 - 9 % 4 * 2); 我打印出来的答案是 3,但答案是 5。谁能告诉我为什么我错了? 最佳答案 乘法、除法和取模具有相同的优先级,并且都比加法和减法具有更高的优
示例输入字符串: (F1 (F2 X (Y) Z) (F3 A B) 我要匹配的是:\w+ 前面没有( 除非后面跟着) 在这种情况下:X、Y、Z、A 和 B 目前的临时解决方法(我知道稍后会给我带来问
我在选择前面的 sibling 时遇到问题。这是 html: Apple A Banana B Strawberry C 我的 XPath:preceding-siblin
是否可以检查 X 和(Y 或 Z)与 mod_rewrite ? 我有以下规则向我的网站的访客提供 dummy.png,他们没有 2 个 cookie 编号 和 认证 设置(我在我的自定义 Drupa
愚蠢的人,但我自己想不出来 - 我如何获得下一个 sexp?就像 preceding-sexp 一样,但是向前。 最佳答案 查看 forward-sexp。你有一个很好的例子here . 好的,根据您
我正在使用文档的股票阶乘运算符,如下所示: factorial = new Operator("!", 1, true, Operator.PRECEDENCE_POWER + 1) {
我正在努力用正则表达式匹配模式替换 Javascript 中的字符串。我想将 {{$myparam}} 的所有匹配项替换为被 span 标签包围。这有效(见下面的代码)。但是我想在匹配前面有 href
我是一名优秀的程序员,十分优秀!