【问题标题】:C++ GCC 4.3.2 error on vector of char-array字符数组向量上的 C++ GCC 4.3.2 错误
【发布时间】:2010-12-06 07:08:36
【问题描述】:

问题和这个bug类似

Question about storing array in a std::vector in C++

但出于不同的原因(见下文)。

对于以下 C++ 示例程序:

#include <vector>

int main(int c_, char ** v_)
{
        const int LENGTH = 100;

        std::vector<char[LENGTH]> ca_vector;

        return 0;

}

GCC 4.2.3 编译干净。 GCC 4.3.2 发出以下错误:

/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:在函数'void std::_Destroy(_Tp*) [with _Tp = char [100 ]]': /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:103: 从 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator =字符 (*)[100]]' /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:128: 实例化自 'void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator& ) [with _ForwardIterator = char (*)[100], _Tp = char [100]]' /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_vector.h:300: 从 'std::vector::~vector() [with _Tp =字符 [100], _Alloc = std::allocator]' test.cpp:7:从这里实例化 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:88:错误:在“* __pointer”中请求成员“~char [100]” ,它是非类类型'char [100]'

原因显然是在

include/g++-v4/bits/stl_construct.h 
  template
    inline void
    _Destroy(_Tp* __pointer)
    { __pointer->~_Tp(); }

我认为这是由于不正确的array-to-pointer-decay.

我的问题是: 语言标准中是否有任何内容阻止在 std::vector 中存储数组? 还是只是那个特殊 GCC 版本中的错误?

我相信这应该可以编译(即 4.2.3 是正确的)。

谢谢 马丁

【问题讨论】:

  • 有什么理由不使用 std::string?
  • 您是说您的代码在 GCC 4.2.3 中编译和执行正确吗?
  • 它仍然可以在那个系统上编译,是的。它似乎有效。
  • @kmarsh:我已经用 std::string 替换了它(从一开始就有);我继承了那段代码,但我不得不承认,我不知道它是非法的(这些天我几乎从不使用原始数组);在得到答案之后,现在应该禁止它似乎很合乎逻辑。而且我不喜欢思考为什么它到目前为止有效以及它是否真的有效......

标签: c++ arrays vector destructor


【解决方案1】:

是的,标准中有一些东西停止使用数组使用Draft C++98 Standard

第 23 节容器

这些组件中存储的对象类型必须满足 CopyConstructible 的要求 types (20.1.3),以及 Assignabletypes 的附加要求。

其中组件是各种容器

20.1.3 包括要求类型必须具有析构函数。

我认为它是一个向量必须复制分配和删除元素。 C++ 如何知道复制或删除 char[] ?

【讨论】:

  • 感谢您的参考,干得好。应该是自己找到的,但是太笨拙了。其他答案也是正确的,我正在标记这个,因为它是最快的。关于马丁
  • 我确定你误读了它。 std::vector&lt;int&gt; 非常合法,即使 int 也没有析构函数。
  • 你可以做 x = new int(5): delete x; - 但是要删除一个数组,你需要 delete []
【解决方案2】:

不,这是不允许的,就像您链接到的问题中不允许这样做一样(我看不出“原因有何不同”)。这两个问题中的任何一个都不是“错误”。或者至少,不是编译器中的错误。就在你的代码中。 ;)

您不能将数组存储在向量中,因为向量要求其元素是可复制构造和可分配的。

【讨论】:

    【解决方案3】:

    最简单的解决方案是:

    std::vector<boost::array<LENGTH> > ca_vector;
    

    这样您就不必为数组/指针的故事而烦恼。 你是否真的想要这个,是另一个问题。

    【讨论】:

    • 感谢您的意见。事实上,在我的具体案例中,vector 是我正在审查的(遗留)源代码中问题的(可能是预期的)解决方案(所以它不是原始字节或任何东西,而只是字符串)。当已经有一个向量时,我完全不确定为什么还有一个 char[]-array 而不是一个字符串;我只能想象原作者的一些晦涩(并且可能被误导)的优化考虑......
    • 如果是字符串,使用字符串。我使用我的构造作为临时解决方案,将基于字节的消息存储在 stl 容器中。
    • 或std::vector<:tr1::array> > ca_vector;
    【解决方案4】:

    请让我知道这段代码的想法。您已经知道,向量也是某种数组,您不必给出初始大小。

    1D vector  ->  std::vector<char*> ca_vector;
    2D vector  ->  std::vector<char*,char*> ca_vector;
    

    【讨论】:

    • 您好,谢谢您的回答。正如您正确指出的那样,我知道向量可以用作数组。我想知道的是上述代码在标准意义上是否合法。我可以在其中放置一个字符串向量 vector 但正如 Mark 所写,一个基本的 C/C++ 数组不满足容器元素的要求。
    • @Aykut: std::vector 没有任何意义。
    • vector 的第二个模板参数不是第二维的类型(向量只有一维)。第二个参数是分配(默认为标准分配器)。
    • 二维向量看起来像:std::vector<:vector> >
    猜你喜欢
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多