2011-11-10 3 views
5

私は現在、GCCの新しいバージョンでコンパイルできるいくつかのコードを見ていますが、古いバージョンではコンパイルできません。私の場合は、std::back_inserterからstd::copyまでのデータを1つのデータ構造からカスタムデータ構造に使用しています。しかし、このカスタムデータ構造のtypedef value_type & const_reference typedefを忘れてしまった場合、これはGCC 4.4でコンパイルされません。同じコードがコンパイルされ、GCC 4.5で正常に動作します。std :: back_inserterは古いGCCでconst_referenceが必要です。どうして?

これらの2つのコンパイラバージョンの違いは、コードをあるバージョンではコンパイルしますが、他のバージョンではコンパイルできません。私は、GCC 4.4ではあまり完全ではないC++ 11の実装と関係があると思います。おそらくdecltypeや別の新しいC++ 11キーワードを使っていると思います。

を使用してconst_referenceタイプを定義しないと、このコードも正しくなりますか?私は通常、STLアルゴリズムライブラリと互換性を持たせるために、typedef(value_typereferenceconst_referenceなど)のフルセットを実装しなければならないと考えましたか?または、私のコードがこの場合にコンパイルされた場合、私は危険な何かを呼び出すつもりはないと思います(例えば、私の他のデータ構造を破壊するセマンティクスの移動)。

+0

(自分のような初心者の時間を節約するのに役立ちます): 'typedef T&reference; typedef const T&const_reference; ' 私のデータ構造に、back_inserterのエラーc2039はなくなりました。 –

答えて

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

と私は両方のコンパイラと同じエラーを取得し、おそらくあなたは、二重チェックする必要がありますあなたが正しいコンパイラのバージョンを使用している場合。

+0

説明をありがとう。 4.5.2ではconst_referenceタイプなしで動作します。 4.4.4にはまだそれが必要です。 – LiKao

+1

@LiKao、最近のGCCでは、デフォルトでC++ 0xライブラリの互換性が有効になっています。 GCC4.5.2は、互換性が無効のときだけ 'const_reference'を使いますが、4.4では無条件で使用しています。 – chill

+0

@chill:[現在のgccバージョンのドキュメント](http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Standards.html#Standards): 'C++言語がない場合のデフォルト方言オプションは、-std = gnu ++ 98.'で与えられます。だから、あなたが言うことを確信していますか? –

1
あなたのデータ構造のために定義され const_referenceを必要とする理由は std::back_insert_iteratorクラスの左辺値引数の型のためのGCC 4.4の代入演算子は次のように定義されているため

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で

、左辺値引数の代入演算子のこの定義は、新しいC++ 11の仕様をサポートするために

template<class Container> 
back_insert_iterator<Container>& 
back_insert_iterator<Container>::operator= 
       (const typename Container::value_type& value); 

に変更されました。あなたのコードはGCC 4.5で正しくコンパイルされているので、私はあなたのデータ構造に適切に定義されたvalue_typeが必要であると仮定しています。

関連する問題