2011-12-12 2 views
5

メンバー変数f(これは関数)を囲むタイプmy_structがあるとします。 fはC++ 11ラムダ関数である可能性があります。タイプがコンパイル時にラムダ式であるかどうかを検出するには?

ラムダオブジェクトに代入するのは不正なので、my_structの代入演算子は、fがラムダの場合は代入されないように実装したいと思います。

ラムダネスのタイプを検査できるタイプ特性is_lambdaを構築することは可能ですか?コードで

:ラムダのタイプは普通、非組合クラス型であるとして、コンパイラをサポートしていない

#include <type_traits> 

template<typename Function> struct is_lambda 
{ 
    // what goes here? 
}; 

template<typename Function> struct my_struct 
{ 
    Function f; 

    my_struct &do_assign(const my_struct &other, std::true_type) 
    { 
    // don't assign to f 
    return *this; 
    } 

    my_struct &do_assign(const my_struct &other, std::false_type) 
    { 
    // do assign to f 
    f = other.f; 
    return *this; 
    } 

    my_struct &operator=(const my_struct &other) 
    { 
    return do_assign(other, typename is_lambda<Function>::type()); 
    } 
}; 

答えて

7

インポッシブル。

§5.1.2 [expr.prim.lambda] p3

(また、クロージャオブジェクトの一種である)ラムダ式のタイプはユニークな、無名癒着不能クラスタイプである[...]

4

おそらく、割り当て不可能な非ラムダ関数を代入したくないので、std::is_assignableを使うことができます。

+0

これはVisual C++ 2015で動作するようですが、それ以前のバージョンでも同様です。単純に: 'std :: is_assignable :: value'を呼び出します。私はこのメソッドを使用して、_EBO_を使用してラムダが派生していないことを確認しました。 –

+0

@MatthewHolderそのようなことは、私の答えのポイントを逃してしまいます。ラムダの特別扱いをしてはならないということです。ラムダから派生することに本質的に間違ったものは何もありません。それは難しいかもしれないいくつかの側面を持っていますが、それらの同じ側面は非ラムダクラスに適用することができます。彼らが割り当てることができないという事実は、それらの一つではないので、あなたのケースでは、それはチェックすべき側面ではないと私は思う。 – hvd

+0

理解できますが、ラムダを検出する必要がある状況は、空の基本最適化のクラステンプレートの基本クラスとして使用されるクラステンプレート型引数にFunctionObjectを渡すときでした。特定の状況や特定のコンパイラでラムダ型を継承することはできないためです。この状況が改善するにつれて、それはもはや問題にはなりません。 –

関連する問題