这是Mac OS X 10.6 C++标准API中的错误吗?

iol*_*olo 6 c++ macos

以下代码无法在Mac OS X 10.6上编译; 它在stl_algobase.h中的"从[...]消息实例化"列表后面给出了一个错误.

#include <vector>

int main( void )
{
    std::vector<int*> *v = new std::vector<int*>( 1, NULL );

    return 0;
}  
Run Code Online (Sandbox Code Playgroud)

为了使它编译,我必须放置一个显式的转换NULL,即替换它(int*)(NULL).
但这看起来有点尴尬,我怀疑它应该是非常必要的; 它还使我的源代码看起来很奇怪的结构和嵌套在命名空间等等的更长的类型名称.

编辑(错误信息):

/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h: In static member function 'static _OutputIterator std::__fill_n<true>::fill_n(_OutputIterator, _Size, const _Tp&) [with _OutputIterator = int**, _Size = int, _Tp = int]':
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:665:   instantiated from '_OutputIterator std::fill_n(_OutputIterator, _Size, const _Tp&) [with _OutputIterator = int**, _Size = int, _Tp = int]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:184:   instantiated from 'void std::__uninitialized_fill_n_aux(_ForwardIterator, _Size, const _Tp&, std::__true_type) [with _ForwardIterator = int**, _Size = int, _Tp = int]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:219:   instantiated from 'void std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = int**, _Size = int, _Tp = int]'  
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:306:   instantiated from 'void std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>) [with _ForwardIterator = int**, _Size = int, _Tp = int, _Tp2 = int*]'  
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_vector.h:790:   instantiated from 'void std::vector<_Tp, _Alloc>::_M_initialize_dispatch(_Integer, _Integer, std::__true_type) [with _Integer = int, _Tp = int*, _Alloc = std::allocator<int*>]'  
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_vector.h:261:   instantiated from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = int, _Tp = int*, _Alloc = std::allocator<int*>]'  
/Users/JayZ/projects/C++/test/main.cpp:6:   instantiated from here
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:641: error: invalid conversion from 'const int' to 'int*'  
Run Code Online (Sandbox Code Playgroud)

如果这可以帮助......

Mic*_*urr 7

发生的事情是编译器必须在vector允许多个参数的构造函数重载之间进行选择:

explicit vector(size_type n, const T& value = T(),
    const Allocator& = Allocator());

template <class InputIterator>
    vector(InputIterator first, InputIterator last,
        const Allocator& = Allocator());
Run Code Online (Sandbox Code Playgroud)

第一个重载(您要匹配)需要转换参数.第二个不需要转换,因为2个参数是相同的类型.这就是编译器选择的重载.不幸的是,该int类型没有第二个构造函数用于这些参数的所有操作.

通过强制使编译器选择第一个构造函数选项,通过强制转换NULLint*或通过使第一个参数unsigned(1U)正确建议的其他答案来强制参数可以避免此问题.

更新:

当我用MinGW 4.5.2编译它时,我得到编译错误(不同的,但出于同样的原因,我相信).但是,当我使用MSVC(2008或2010)构建时,我没有错误.当我查看MSVC生成的代码时,它实际上匹配第二个重载(使用2个迭代器)而不是"大小和默认值"重载.

"Aha",我认为,"这会在某个地方运行时崩溃,因为迭代器具有价值1并且0没有任何意义".

但是,当该构造函数的'迭代器'类型恰好是int,MSVC实现执行的'计数/初始值'构造vector.

标准说明当构造函数的InputIterator参数满足InputIterator的要求时,构造函数必须执行的操作.由于int不符合InputIterator的要求,实现有一些自由的统治来做其他事情.标准说"一个实现可以在一个类中声明额外的非虚拟成员函数签名"(17.4.4.4),这将涵盖MSVC的行为,我相信.标准也允许您看到的以及我在GCC 4.5.2中看到的产生错误诊断的行为.

我确信MSVC的行为是大多数用户想要和想要的(直到他们转移到其他编译器的代码).这当然很聪明.