2016-10-18 10 views
2

私は答えhttps://stackoverflow.com/a/7943765/7006673で発生し、次のコードテンプレートの特殊

template <typename T> 
struct function_traits 
    : public function_traits<decltype(&T::operator())> 
{}; 
// For generic types, directly use the result of the signature of its 'operator()' 

template <typename ClassType, typename ReturnType, typename... Args> 
struct function_traits<ReturnType(ClassType::*)(Args...) const> 
// we specialize for pointers to member function 
{ 
    // ... 
} 

int main() 
{ 
    auto lambda = [](int i) { return long(i*10); }; 

    typedef function_traits<decltype(lambda)> traits; 

    // ... 

    return 0; 
} 

を理解する難しさを持っています。ここで

template <typename ClassType, typename ReturnType, typename... Args> 
struct function_traits<ReturnType(ClassType::*)(Args...) const> 

template <typename T> 
struct function_traits 

テンプレートクラスの特殊化を示しているようだが、専門template <typename ClassType, typename ReturnType, typename... Args>のテンプレートパラメータリストは(すなわち、template <>と等しくない空ではありません)。 誰かが理解してもらえますか?これはどのような特殊化ですか、テンプレートパラメータClassType,ReturnTypeArgsはどのように導き出されますか?

事前に感謝します。

答えて

2

これはpartial specializationです。 type_traitsは、明示的にインスタンス化されています

T = ReturnType(ClassType::*)(Args...) const 

しかし、これTReturnTypeClassType、およびArgsに依存しています。そのため、宣言にはtemplate <>(​​)がありませんが、特定の種類のTを記述する新しいパラメータを持つテンプレート宣言があります。

テンプレートパラメータClassType、ReturnType、およびArgsがどのように推定されますか?

テンプレートは、この特殊化に適した式でインスタンス化されたときに導出されます。ここでは、ReturnType(ClassType::*)(Args...) constはメソッドへのポインタでのみ置き換えることができます。

これはSFINAEの例です。

+0

ありがとうございます。 1つの質問が残っています:タイプ控除は、関数のテンプレートパラメータに対してのみ行うことができ、構造体やクラスのものではないと思いました。間違っていますか? –

+0

暗黙的なインスタンス化は、関数のテンプレートパラメータに対してのみ実行できます。関数を呼び出すときに引数を明示的に渡すため、その型を暗黙的に推論することができます。ここで 'function_traits 'は 'T = decltype(lambda)'を使った明示的なインスタンス化です – wasthishelpful

+0

ありがとう! 'decltype(lambda)'はテンプレートパラメータなので、 'returnType'、' ClassType'、 'Args'を' decltype(lambda) 'に基づいて減算することができます。 –

2

これは部分的な特殊化です。それはちょうどtypename Tを取る何かのような「何か」であってはいけませんが、まだそれには多少のばらつきがあります。

また、元の構造体/クラスのテンプレート行の型の数と、特殊化の名前の後の<...>があります。それは非対称であるので、奇妙なものです。あなたの部分的な特殊化で

まだ唯一のシングルタイプの作成組み合わせたテンプレートの種類のすべての3つの
struct function_traits<ReturnType(ClassType::*)(Args...) const> 

- メンバ関数へのポインタを。これは、「親」テンプレート型と同じ数の型です。ただし、その単一型は、特殊化では3つのテンプレート化型に分類されます。これは専門のどのような

// this is what I'm calling the "master template", this isn't an official term 
template<class A, class B, ......., class N> 
class Foo{}; 

template</*...This can have as many (or 0) entries as you need for this specialization...*/> 
class Foo</*...This must have the same number as master template above, but can be broken down into as many smaller pieces as you want...*/> {}; 
関連する問題