考虑一下:
std::vector<int*> v(1, 0);
使用VC ++ 10可以很好地编译(即使在最大警告级别也没有警告)。但是,它不能在linux上使用llvm或在linux上使用gcc进行编译,从而产生类似“从不兼容的类型const int分配给int *”的错误。我不是在寻找解决方案 - 我知道第二个参数是不必要的,或者static_cast修复了错误。
我认为零可以隐式转换为任何指针类型。是什么赋予了?我可以做到以下几点:
int* i = 0;
int* const& ii = 0;
const int t = 0;
i = t;
我理解向量构造函数签名需要const T&
,当vector<int*>
展开时,int* const&
变为正确吗?有人可以解释这里发生了什么,以及VC ++或非VC ++编译器是否正确?
答案 0 :(得分:2)
std::vector
有一个讨厌的构造函数,带有这个签名
template <class InputIterator>
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
如果编译器从您的参数InputIterator
和int
中将0
从1
(!)中扣除,那将非常合适,但不能满足我们的要求。
我相信C ++ 11要求编译器更加努力地弄清楚参数是否实际上是迭代器。在C ++ 03中,它们最终可能会以size_type(1)
和int(0)
结束,从而导致您的问题。
整数文字0可转换为空指针,但值为0的int
不是!
答案 1 :(得分:2)
看起来g ++实际上错了。见C ++ 98 23.1.1 / 9:
对于本节和第21节中定义的每个序列:
- 构造函数模板X(InputIterator f, InputIterator l,const Allocator&amp; a =分配器())
应具有相同的 效果为:
X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a)
如果InputIterator是 积分型。
请注意,InputIterator
是构造函数的模板参数,在本例中,对于您的示例,它将是int
,因此是一个整数类型。 g ++库实际上有特定的代码来处理存储在vector
中的类型也是完整的所有情况,这些都将正常工作。在这种情况下,仅仅因为您使用了0
,标准规定的static_cast
实际上是合法的。我尝试编译标准所说的应该是等效的代码,然后用g ++ 4.5编译。