我目前正在查看一些可以在较新版本的GCC上编译但不能在旧版本上编译的代码。在我的情况下,我使用std::back_inserter
到std::copy
从一个数据结构到自定义数据结构的一些数据。但是,如果我忘记了此自定义数据结构中的typedef value_type & const_reference
typedef,则无法在GCC 4.4上编译。相同的代码在GCC 4.5上编译并运行得很好。
这两个编译器版本之间有什么区别,这使得代码在一个版本上编译而在另一个版本上编译。我猜它与C ++ 11的实现有关,这在GCC 4.4中完全不那么完整。可能有decltype
或其他新的C ++ 11关键字,我猜。
如果我在没有定义std::back_inserter
类型的情况下使用const_reference
,这段代码也是正确的吗?我通常认为必须实现一整套typedef(value_type
,reference
,const_reference
等)才能与STL算法库兼容?或者我可以安全地假设,如果我的代码在这种情况下编译,我不会调用任何危险的东西(例如移动语义,这会破坏我的其他数据结构)。
答案 0 :(得分:6)
标准(1998)说std::back_insert_iterator
需要Container::const_reference
。在“24.4.2.1 Template class back_insert_iterator”,[lib.back.insert.iterator]中,它说:
back_insert_iterator<Container>&
operator=(typename Container::const_reference value);
2011年标准只需要Container::value_type
,
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
back_insert_iterator<Container>&
operator=(typename Container::value_type&& value);
因此,要兼容两个版本的C ++标准,请同时定义value_type
和const_reference_type
。
在GCC 4.4.6和4.5.1中,operator=
的定义相同(libstdc++-v3/include/bits/stl_iterator.h
):
back_insert_iterator&
operator=(typename _Container::const_reference __value)
{
container->push_back(__value);
return *this;
}
我和两个编译器都有同样的错误,也许你需要仔细检查你是否使用了正确的编译器版本。
答案 1 :(得分:1)
您需要为数据结构定义const_reference
的原因是因为GCC 4.4中std::back_insert_iterator
类中的左值参数类型的赋值运算符被定义为:
template<class Container>
back_insert_iterator<Container>&
back_insert_iterator<Container>::operator=
(typename Container::const_reference value);
因此,const_reference
必须是类类型中的可解析标识符才能在std::back_insert_iterator
类模板中正确实例化赋值运算符。
在GCC 4.5中,左值参数赋值运算符的定义已更改为
template<class Container>
back_insert_iterator<Container>&
back_insert_iterator<Container>::operator=
(const typename Container::value_type& value);
以支持新的C ++ 11规范。由于您的代码使用GCC 4.5正确编译,我假设您必须为您的数据结构正确定义value_type
。