【问题标题】:Explicitly initializing vector of pointers results in conversion error?显式初始化指针向量会导致转换错误?
【发布时间】:2012-04-04 19:03:42
【问题描述】:

考虑一下:

std::vector<int*> v(1, 0);

这在 VC++10 上编译得很好(即使在最大警告级别也没有警告)。但是,它不能在 mac 上使用 llvm 或在 linux 上使用 gcc 进行编译,从而出现类似“从不兼容的类型 const int 分配给 int*”之类的错误。我不是在寻找解决方案——我知道第二个参数是不必要的,或者 static_cast 修复了错误。

我认为零可以隐式转换为任何指针类型。是什么赋予了?我可以做到以下几点:

int* i = 0;
int* const& ii = 0;
const int t = 0;
i = t;

我知道向量构造函数签名采用const T&amp;,当扩展为vector&lt;int*&gt; 时变为int* const&amp; 对吗?有人能解释一下这里发生了什么,VC++ 还是非 VC++ 编译器是否正确?

【问题讨论】:

  • 尝试nullptr 而不是0
  • 你是编译成 C++03 还是 C++11 程序?
  • 与问题无关,但是,为什么Bjarne said we should avoid them 时使用原始指针?
  • 这在我看来像是一个编译器错误。
  • 谢谢大家——这就是我喜欢 stackoverflow 的原因。这是一个涉及移植遗留代码的学术问题,我已经找到了解决方案。我非常了解现代 c++ 在内存管理方面的使用,但感谢您的娱乐性和毫无意义的玩笑。

标签: c++ visual-c++


【解决方案1】:

看起来 g++ 在这里实际上是错误的。见 C++98 23.1.1/9:

对于本节和第 21 节中定义的每个序列:

—— 构造函数模板 X(InputIterator f, InputIterator l, const Allocator& a = Allocator())

应该有相同的 效果为: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 编译。

【讨论】:

  • 干得好。 std::vector&lt;int&gt; v(1, 0); 编译得很好。我没想到MS在这里是正确的。
  • 这取决于实现是否考虑了Library Issue #438,它表示这不起作用。建议的解决方案是X(static_cast&lt;typename X::size_type&gt;(f), l, a),它与 Tabber 的失败相匹配。 C++11 紧随 Defect Report #1234 之后,结果再次不同。
【解决方案2】:

std::vector 有一个带有这个签名的讨厌的构造函数

template <class InputIterator>
vector(InputIterator first, InputIterator last,
       const Allocator& = Allocator());

如果编译器从您的参数01 中扣除InputIteratorint(!),这将是一个很好的选择,但不是我们想要的。

我相信 C++11 要求编译器更加努力地确定参数是否实际上是迭代器。在 C++03 中,它们可能会以 size_type(1)int(0) 结尾,从而导致您的问题。

整数文字 0 可以转换为空指针,但值为 0 的 int 则不行!

【讨论】:

  • 谢谢。你是对的——更仔细地查看错误,我现在看到模板化构造函数的实例化位于错误树的根部。我现在只是想知道为什么 VC++(甚至是 c++11 之前的支持)在这里调用预期的构造函数会遇到额外的“麻烦”,并且这样做违反了语言规则(毕竟,模板化的构造函数是更好的匹配)?
  • @Bo Persson 如果我正确阅读 23.1.1/9,这不是正确答案:g++ 实际上错过了一个特殊情况。
猜你喜欢
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
相关资源
最近更新 更多