2011-10-01 8 views
11

私はちょうどthis really nice talkを見たことがあります。ロックハード:C++ Evilving Boris Jabes。 高次ジェネリックプログラミングに関する話のセクションでは彼は次のようにその戻り値の型にに関してより一般的な関数の一例であり、少数のテンプレート関数につながる啓発C++の使用法11 decltype

template <typename Func> 
auto deduce(const Func & f) -> decltype(f()) 
{..} 

これをオーバーロードすることを言いますしかし

template <typename Func> 
Func deduce(const Func & f) 
{..} 

はので、私は本当にdecltypeのユニークな能力を示していない選択された例を推測し、次のようにプレーンなテンプレート構文を使用して実現することができます。誰もそのようなより多くの例を与えることができますの使用法decltypeの使用?容器CのVALUE_TYPEをAutodeducting

+7

号最初の例では、 ''推測(F) '' '' Func'''の結果の型を返すことを意味します。 2番目の例は、 '' '' '(f)' ''が '' Func'''を返すことを意味します。違いが分かりますか? –

+0

ああ、申し訳ありませんが、 'decltype'の引数の中に余分な'() 'がありませんでした。私の間違い。 –

答えて

25

あなたの疑惑は間違っています。

void f() { } 

は今deduce(&f)voidを入力しているが、あなたのリライトで、それはvoid(*)()を入力しています。いずれの場合でも、式または宣言の型を取得する場合は、decltypeを使用します(これらの2つの微妙な違いに注意してください)。decltype(x)は必ずしもdecltype((x))と同じではありません。例えば

、それはおそらくあなたの標準ライブラリの実装は、どこか

using size_t = decltype(sizeof(0)); 
using ptrdiff_t = decltype((int*)0 - (int*)0); 
using nullptr_t = decltype(nullptr); 

のような行addの正しい戻り値の型は、過去のC++を通じて困難な問題となっている見つけるが含まれています。これは簡単な運動です。

template<typename A, typename B> 
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; } 

ほとんど知られていないが、あなたが::前と疑似デストラクタ名、私はそれを使用

// has no effect 
(0).~decltype(0)(); 

// it and ite will be iterators into an initializer list 
auto x = { 1, 2, 3 }; 
decltype(x)::iterator it = x.begin(), ite = x.end(); 
+1

これを少し説明してください: '(0)。〜decltype(0)();'?私はそれを得ることはないと思う。 –

1
std::for_each(c.begin(), c.end(), [](decltype (c.front()) val){val*=2;}); 

decltypeことなく行うことができません。

+1

ラムダを使用している場合にのみ、polymorphicではない(ただし、それらがC++であることを期待している)場合には、これを行うことはできません。多相関数オブジェクトを使用していた場合は、それが自動的に導出されます。 –

0

一箇所にdecltypeを使用することができるということです、私は同じ型を持たなければならない変数を作るために必要な場所であります別の変数の将来的には同じかどうかは分かりません。

void foo(int a)//maybe in future type of a changed 
{ 
    decltype(a) b; 
    //do something with b 
} 
関連する問題