2017-01-19 17 views
4
をCONSTに適用

私が与える場合のstd :: result_ofは、オーバーロードされたメソッド

typedef std::vector<int> v; 

以下(代替v::const_iteratorを使用することであるが、これはconst_iteratorに依存する定数イテレータの種類を捕捉するために使用することができますメンバーのタイプは、明示的にクラスで定義されている。

typedef typename std::result_of<decltype(&v::cbegin)(v*)>::type const_iterator; 

を確かに、我々は上記の私たちが望むようないことを確認することができます。

static_assert(std::is_same<const_iterator, typename v::const_iterator>::value); 

しかし、私は以下でコンパイラの失敗を見つける。

typedef typename std::result_of<decltype(&v::begin)(v*)>::type iterator; 

コンパイラは、メソッドが(const修飾子によって)オーバーロードされていると不平を言うと戸惑うことがあると文句を言います。しかし、私はあいまいさを解決する構文を見つけることができません。少なくともconstバージョンだけがconstオブジェクトで動作できるので、以下は明白であると予想します。しかし、以下にも同様に問題がある。

typedef typename std::result_of<decltype(&v::begin)(const v*)>::type const_iterator2; 

beginの特定のconstまたはnonconstバージョンをどのように参照しますか?

答えて

4

次はあなたが欲しいものを行います。ここ

using v = std::vector<int>; 
using iter = decltype(std::declval<v>().begin()); 
static_assert(std::is_same<iter, typename v::iterator>::value); 

問題は&v::beginがあいまいであるということです。 2つのv::begin関数があり、&演算子は、どちらのアドレスを返すかを知る方法がありません。 std::declvalを使用してその周りに取得します。戻り値の型がstd::declval<v>()であるので、vです。コンパイラは、非const v::begin()に興味があることを知っています。何のオブジェクトが、このコードで作成されていないことを

using citer = decltype(std::declval<const v>().begin()); 
static_assert(std::is_same<citer, typename v::contst_iterator>::value); 

注:

同様に、以下はあなたのconstバージョンを取得します。 std::declvalには定義がないため、decltypeのような未評価のコンテキストでのみ動作します。

+0

私はこのレスポンスを追加しましたが、上記の 'v *'引数の 'const'修飾子があいまいさを解決しないのはなぜですか? – epl

+0

'std :: declval ()'の戻り値の型は 'v'ではありません。 – skypjack

+0

@eplは、 '&'がパラメータを見ている前に曖昧な関数名のアドレスを取得しようとしましたが失敗したためです。 –

関連する問題