5

現在、GCC の新しいバージョンではコンパイルできるが、古いバージョンではコンパイルできないコードを検討しています。私の場合、あるデータ構造からカスタム データ構造までのデータを使用しstd::back_inserterています。ただし、このカスタム データ構造std::copyの typedef を忘れると、 GCC 4.4 でコンパイルされません。typedef value_type & const_reference同じコードは、GCC 4.5 で問題なくコンパイルおよび実行されます。

これらの 2 つのコンパイラ バージョンの違いは何ですか。コードは一方のバージョンではコンパイルされますが、もう一方のバージョンではコンパイルされません。GCC 4.4 では完全ではなかった C++11 の実装と関係があると思います。おそらく何か、decltypeまたは別の新しい C++11 キーワードがあると思います。

std::back_inserterまた、型を定義せずに を使用した場合、このコードは正しいconst_referenceですか? 通常、STL アルゴリズム ライブラリと互換性を持たせるには、typedef の完全なセット ( 、value_typeなど) を実装する必要があると考えていました。または、この場合にコードがコンパイルされた場合、危険なもの (たとえば、他のデータ構造を破壊する移動セマンティクス) を呼び出していないと安全に想定できますか?referenceconst_reference

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_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;
  }

両方のコンパイラで同じエラーが発生します。おそらく、正しいコンパイラ バージョンを使用しているかどうかを再確認する必要があります。

于 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 に答える