【问题标题】:std::for_each compile error with g++, not VS2012std::for_each 使用 g++ 编译错误,而不是 VS2012
【发布时间】:2012-10-06 05:13:15
【问题描述】:

我有以下代码(尽可能简化):

#include <vector>
#include <algorithm>

using std::vector;

enum class Foo {
    BAR, BAZ
};

void print_to_file(const vector<const vector<Foo> >& sequences) {
    std::for_each(sequences.begin(), sequences.end(), [](const vector<Foo>& sequence) {
    });
}

int main(int argc, char **argv) {
    return EXIT_SUCCESS;
}

当使用g++ (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773] 编译为g++ --std=c++11 test.cpp 时,我收到以下错误消息:

In file included from /usr/include/c++/4.7/x86_64-suse-linux/bits/c++allocator.h:34:0,
                 from /usr/include/c++/4.7/bits/allocator.h:48,
                 from /usr/include/c++/4.7/vector:62,
                 from test.cpp:1:
/usr/include/c++/4.7/ext/new_allocator.h: In instantiation of ‘struct __gnu_cxx::new_allocator<const std::vector<Foo> >’:
/usr/include/c++/4.7/bits/allocator.h:89:11:   required from ‘class std::allocator<const std::vector<Foo> >’
/usr/include/c++/4.7/bits/alloc_traits.h:89:43:   required from ‘struct std::allocator_traits<std::allocator<const std::vector<Foo> > >’
/usr/include/c++/4.7/ext/alloc_traits.h:109:10:   required from ‘struct __gnu_cxx::__alloc_traits<std::allocator<const std::vector<Foo> > >’
/usr/include/c++/4.7/bits/stl_vector.h:76:28:   required from ‘struct std::_Vector_base<const std::vector<Foo>, std::allocator<const std::vector<Foo> > >’
/usr/include/c++/4.7/bits/stl_vector.h:208:11:   required from ‘class std::vector<const std::vector<Foo> >’
test.cpp:11:25:   required from here
/usr/include/c++/4.7/ext/new_allocator.h:83:7: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const std::vector<Foo>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::vector<Foo>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::vector<Foo>&]’ cannot be overloaded
/usr/include/c++/4.7/ext/new_allocator.h:79:7: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const std::vector<Foo>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::vector<Foo>*; __gnu_cxx::new_allocator<_Tp>::reference = const std::vector<Foo>&]’

相同的代码在 VS2012 下编译良好,但在 g++ 下严重失败,我完全不知道如何解释错误消息。

【问题讨论】:

  • 在 MinGW 的 g++ 4.7.0 下编译良好。
  • @Yuushi 我正在从 OpenSuse 运行标准安装,如果除了 g++ --version 字符串之外我应该包含任何其他内容以进行诊断,请告诉我。
  • 尝试使用 g++ -v 来获取它在构建时是如何配置的列表

标签: c++ visual-c++ c++11 g++


【解决方案1】:

我很惊讶您在其他地方没有遇到问题,因为 vector&lt;const vector&lt;Foo&gt; &gt; 不是可能的数据类型。

std::vector 的 value_type 必须至少是可复制构造 (C++03) 或可移动 (C++11)。如果它是 const,则不能分配或移动它。

【讨论】:

  • 令人惊讶的是它适用于 MinGW 下的 g++。 Hum const 对于它的小效果来说真的太多了。所以外卖是我不能在向量中拥有恒定的东西?
  • 这取决于你在做什么。有些事情可能会发生在某些编译器上,但这只是偶然。当您插入或删除对象时,实现可能必须在向量内移动东西,如果元素是 const,它就不能这样做。
  • const std::vector&lt;Foo&gt; 不可复制如何构造?分配是明确的,但构造没有问题。
【解决方案2】:

用于标准容器的分配器要求不允许容器持有const 对象。 C++11 17.6.3.5“分配器要求”概述了使用以表 27 开头的一组表的标准分配器的要求。在表 27 中,第一个定义是针对“描述性变量”TU、和C,它们被定义为“任何非const,非引用对象类型”。用于分配器类定义的描述性变量XY 是:

X - T 类型的分配器类

Y - U 类型对应的分配器类

总之,标准分配器是根据非常量类型的参数化定义的。

有一个旧的 GCC/libstdc++ 错误(已解决为无效)可以追溯到 2004 年(C++2003 对在容器中存储 const 对象有类似的限制,但它更容易显示,因为 2003 标准更直截了当地说存储在容器中的对象类型必须是“可分配的”)。

【讨论】:

  • 是的,错误报告中的一些 cmets 基本上描述了我想要做什么。拥有一个标准的不可变对象集合似乎不是不合理或很少有用的。太糟糕了,似乎没有办法(至少很简单)来做到这一点。
猜你喜欢
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2015-05-08
相关资源
最近更新 更多