2013-01-18 15 views
5

アルゴリズム内でラムダに要素を渡す、私は参照ツーのconstで要素を受け入れラムダを作成したい:参照ツーのconst

template<typename Iterator> 
void solve_world_hunger(Iterator it) 
{ 
    auto lambda = [](const decltype(*it)& x){ 
     auto y = x; // this should work 
     x = x;  // this should fail 
    }; 
} 

コンパイラはこのコードを好きではありません:

Error: »const«-qualifier cannot be applied to »int&« (translated manually from German)

は、その後、私はdecltype(*it)はすでに参照され、そして当然のことながら、それらがconst行うことができないことに気づきました。 constを削除すると、コードがコンパイルされますが、x = xが失敗します。

私はプログラマー(私です)を1分信頼して、constと明示的な&を取り除きましょう。これは参照折りたたみルールのために削除されてしまいます。しかし、待って、decltype(*it)実際は、基準となるを保証されている、または私は安全側にあることを明示的&を追加する必要がありますか?

我々は、プログラマを信用していない場合、私は問題を解決するには、2つの解決策を考えることができます:

(const typename std::remove_reference<decltype(*it)>::type& x) 

(const typename std::iterator_traits<Iterator>::value_type& x) 

あなたは醜悪である1自分で決めることができます。理想的には、ターゲット・オーディエンスがこれまでにこれまで聞いたことがないので、テンプレート・メタプログラミングを含まないソリューションが必要です。だから、:

質問1:decltype(*it)&は常にdecltype(*it)と同じですか?

質問2:どのように私は、テンプレートメタプログラミングなしで参照ツーのconstで要素を渡すことができますか?

+2

英語のエラーが良いでしょう! :) – Pubby

+0

@Pubby私はベストを尽くして、修正を自由にしてください:) – fredoverflow

+0

@seheはトップレベルのconstに関するものではありません。 –

答えて

4

質問1:いいえ、InputIterator上の要件は*itは(「イテレータ要件」に、テーブル72)Tに変換可能であることに過ぎません。

のでdecltype(*it)は、例えばvalue_typeintあるイテレータのためのconst char&である可能性があります。または、intにすることもできます。またはdoubleiterator_traitsを使用して

は、あなたがしたいか決めdecltypeを使用するのと同じではありません。

同じ理由で、auto value = *it;ではありません。は必ずイテレータの値タイプで変数を与えます。

質問2:テンプレートのメタプログラミングによって何を意味するかによって異なります。

特性型をTMPとすると、iterator_traitsは任意のイテレータの値型にアクセスする唯一の手段であるため、TMPなしで「イテレータの値型へのconst参照」を指定する方法はありません。

、あなたはこのことについてどのように、その後decltypeをCONST-IFYしたい場合は?あなたは、そのタイプを使用するためにret_typeをキャプチャする必要がある場合があります

template<typename Iterator> 
void solve_world_hunger(Iterator it) 
{ 
    const auto ret_type = *it; 
    auto lambda = [](decltype(ret_type)& x){ 
     auto y = x; // this should work 
     x = x;  // this should fail 
    }; 
} 

、私は簡単に、現時点では確認することができません。

残念ながら、イテレータは余分な時間を逆参照します。それを避けるために巧妙なコードを書いてもいいかもしれませんが、巧妙なコードはremove_referenceの代替バージョン、つまりTMPになります。

+0

さて、私は弾を噛んで、iterator_traitsを説明します。 – fredoverflow

+0

@FredOverflow:本/チュートリアルを書く? –

+0

Nope。もし私が本を書いたら、ラウンジが最初に知っているだろうと確信している;) – fredoverflow

関連する問題