2012-10-16 39 views
2

我有以下代码(尽可能多的简化为可能的):的std ::的for_each编译克误差++,不VS2012

#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 ++下失败,我没有丝毫的想法如何解释错误信息。

+1

编译下克++中的MinGW 4.7.0细。 – Yuushi

+0

@Yuushi我正在运行OpenSuse的标准安装,如果除了'g ++ --version'字符串之外我还需要包含一些诊断信息,请告诉我。 – Voo

+0

尝试使用g ++ -v来获取它在构建时如何配置的清单 – Yuushi

回答

5

我很惊讶你不会在别处遇到问题,因为这个vector<const vector<Foo> >不是可能的数据类型。

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

+0

令人惊讶的是它适用于MinGW下的g ++。嗡嗡声'const'对于它所具有的小效果来说真的是太多了......所以外带的是我不能在矢量中保持常量。 – Voo

+0

这取决于你在做什么。有些事情可能适用于某些编译器,但这只是偶然。当插入或删除对象时,实现可能需要在矢量内部移动东西,如果元素是常量,则不能这样做。 –

+0

'const std :: vector '不可复制构造吗?作业是一个明确的不,建设,但没有问题。 – Yakk

3

用于标准容器的分配器要求不允许const对象被容器占用。 C++ 11 17.6.3.5“分配器要求”概述了使用从表27开始的一组表格的标准分配器的要求。在表27中,第一个定义适用于'描述性变量'TUC,它们是定义为“任何非常量,非参考对象类型”。描述性变量XY,用于分配器类defintions,有:

X - 类型T

Y一个分配器类 - 的相应分配器类型U

在总结,标准分配器是通过非常量类型的参数化定义的。

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

+0

是的,在bug报告中的一些评论基本上描述了我想要做的事情。拥有标准的不可变对象集合似乎不合理或很少有用。太糟糕了,似乎没有办法(至少直截了当)做到这一点。 – Voo