考虑以下代码:
#include <vector>
struct A
{
explicit A(int i_) : i(i_) {}
int i;
};
int main()
{
std::vector<int> ints;
std::vector<A> As(ints.begin(), ints.end());
}
上面的代码应该编译吗?我的感觉是不应该,因为构造函数被标记为 explicit
.
Microsoft Visual C++ 同意,给出明确的错误信息:cannot convert from 'int' to 'const A'; Constructor for struct 'A' is declared 'explicit'
但是,使用 Comeau's online compiler , 代码编译成功。
哪个是正确的?
编辑:
有趣的是,改变vector
至 set
(在向 A 添加 operator <
之后)导致两个编译器都给出错误。
但是,改变 vector<int>
至 map<int, int>
和 vector<A>
至 map<A, A>
导致两个编译器都接受代码!
最佳答案
我查看了 GCC 的 STL 实现,它应该有类似的行为。原因如下。
- 元素
vector
由接受任何两种类型的通用函数模板初始化X
和V
并调用new( p ) X( v )
其中v
是V
(我在解释一下)。这允许显式转换。 - 元素
set
或map
由_tree<T,…>
的私有(private)成员函数初始化特别期待T const &
要传入。此成员函数不是模板(除了是模板的成员之外),因此如果初始值不能隐式转换为T
,调用失败。 (我再次简化了代码。)
该标准不要求在使用范围初始化容器时显式转换有效或隐式转换无效。它只是说范围被复制到容器中。对于您的目的来说绝对是模棱两可的。
令人惊讶的是,存在这样的歧义,考虑到他们已经在考虑 the one I had 等问题的情况下改进了标准。几周前。
关于C++ 显式构造函数和迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2003266/