std :: back_inserter需要旧GCC上的const_reference。为什么?

时间:2011-11-10 14:30:24

标签: c++ stl stl-algorithm

我目前正在查看一些可以在较新版本的GCC上编译但不能在旧版本上编译的代码。在我的情况下,我使用std::back_inserterstd::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_typereferenceconst_reference等)才能与STL算法库兼容?或者我可以安全地假设,如果我的代码在这种情况下编译,我不会调用任何危险的东西(例如移动语义,这会破坏我的其他数据结构)。

2 个答案:

答案 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_typeconst_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