【发布时间】:2014-12-01 17:06:46
【问题描述】:
以下代码可以正常工作:
#include <iostream>
struct B
{
operator int()
{
return int();
}
};
struct A
{
A(int, int){ std::cout << "A(int, int)" << std::endl; }
};
A a({B(), B()});
int main()
{
}
并产生输出:
A(int, int)
但我不明白为什么?标准的内容是:
但是,当考虑构造函数的参数或 用户定义的转换函数,它是 13.3.1.3 的候选函数,当 在第二步中调用用于临时复制/移动 13.3.1.7 传递初始化器时的类复制初始化 列表作为单个参数或当初始化列表正好有一个 元素和到某个类 X 或引用的转换(可能 cv-qualified) X 被认为是构造函数的第一个参数 X [...] 只考虑标准转换序列和省略号转换序列
所以在我们的例子中,我们考虑了构造函数的参数(它是{B(), B()})。更准确地说,我们将 initializer-list 作为单个参数传递(我引用的规则中的第二种情况)。现在,我们需要将初始化列表的第一个元素(B 类型的临时元素)转换为int,唯一的方法是应用用户定义的转换(B::operator int())。但是,正如我在规则末尾所说的,只考虑了标准转换序列和省略号转换序列。由于该代码不应该工作,它应该抛出类似A(int, int) 不可行或类似的错误。
怎么了。可能是一个错误?
【问题讨论】:
-
在 N4140 中找不到此报价。你引用的是什么草稿和段落?
-
@Columbo: C++11 13.3.3.1/4
标签: c++ c++11 language-lawyer implicit-conversion