2017-10-03 6 views
0

size()メソッドとsize_type定義を持つ任意のコンテナのサイズを返す汎用関数を作成しようとしています。これまでのところ私は2つのアプローチを試してみましたが、どちらもコンパイルされていない:テンプレートのパラメータとしてコンテナのdecltypeフィルタリング

std::vector<int> vec; 
auto sz = len(vec); 

を明らかに、私は削除する場合:

1.

template <typename Cont> 
auto len(Cont const& cont) -> decltype(std::declval<Cont&>().size(), Cont::size_type) 
{ 
    return cont.size(); 
} 

2.

template <typename T, template <typename U, typename = std::allocator<U>> typename Cont> 
auto len(Cont<T> const& cont) -> decltype(std::declval<Cont<T>&>().size(), Cont<T>::size_type) 
{ 
    return cont.size(); 
} 

はそれをテストしようとすると、末尾のdecltype()は、すべてが期待どおりに動く。私はこれがstd::enable_ifでも達成できると知っていますが、教育的にはこれを理解しなければなりません。私が紛失しているものを説明してください。

P.S.質問を重複としてマークしようとする人にとって、私は "どこで、なぜ"テンプレート "と" typename "キーワードを入れなければならないのかと問いません。まだこれは私があなたがtypenameを追加する必要があり、括弧のカップル

decltype(std::declval<Cont&>().size(), typename Cont::size_type{}) 
// ....................................^^^^^^^^................^^ 

typenameCont内、size_typeがタイプであることを言うために必要とされる

+0

Btw、 'std :: size()' ... – HolyBlackCat

+0

ええ、私は知っています。ポイントは、私が実装しようとしている唯一の機能ではないので、パターンを正しく取得する必要がありました。 – aquila

+1

'std :: declval'は' cont'へのアクセス権があるので余計ですが、 'decltype(cont.size()、typename Cont :: size_type)'と書くことができます。 – Holt

答えて

2

を欠けている何かであることを、考え出したていません。

括弧について... decltype()はオブジェクトの種類を返します。あなたは、単に

decltype(typename Cont::size_type) 

を記述する場合、あなたはタイプからタイプを検出するために頼むとdecltype()は、このように動作しません。 decltype()が型を検出できるように、タイプCont::size_type(括弧)のオブジェクトを作成する必要があります。

+0

ああ、そういう愚かな落とし穴のタイプ**のタイプ名**。どうもありがとう!宣言型をこのように使うことができたのは初めてのことでした。 – aquila

関連する問題