5

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

4

2 回答 2

6

标准 (1998) 说std::back_insert_iterator需要Container::const_reference. 在“24.4.2.1 模板类 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;
  }

而且我在两个编译器上都遇到了同样的错误,也许你需要仔细检查你是否使用了正确的编译器版本。

于 2011-11-10T15:04:02.370 回答
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为您的数据结构正确定义。

于 2011-11-10T14:58:42.597 回答