2011-12-12 21 views
5

Załóżmy, że mam typ my_struct zawierający zmienną składową, f, która jest funkcją. Jest możliwe, że f jest funkcją lambda C++ 11.Jak wykryć, czy typ jest wyrażeniem lambda w czasie kompilacji?

Ponieważ niedozwolone jest przypisywanie obiektów lambda, chciałbym wdrożyć operatora przypisania my_struct w taki sposób, że gdy f jest lambda, nie jest on przypisywany.

Czy można zbudować typ obiektu is_lambda, który może sprawdzić typ dla lambda-ness?

W kodzie:

#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()); 
    } 
}; 

Odpowiedz

7

bez wsparcia kompilator jako typ lambda tylko zwykły, do związków typu klasy.

§5.1.2 [expr.prim.lambda] p3

Typem lambda ekspresji (który również jest typ obiektu zamknięcia) jest unikalnym, Nienazwana zrostu klasy typu [...]

4

Prawdopodobnie nie chcesz także przypisywać nieprzenoszalnych funkcji nie-lambda, więc możesz użyć std::is_assignable.

+0

To wydaje się działać w Visual C++ 2015, może w starszych wersjach. Używając po prostu: 'std :: is_assignable :: value'. Użyłem tej metody, aby zapewnić, że lambda nie została wyprowadzona podczas używania _EBO_. –

+0

@MatthewHolder Taki rodzaj pomyłki jest jednak kwestią mojej odpowiedzi, a mianowicie, że nie powinieneś próbować traktować lambdas jako specjalnego traktowania. Z lambda nie ma nic nie w porządku. Ma pewne aspekty, które mogą sprawiać trudności, ale te same aspekty mogą dotyczyć klas innych niż lambda. Fakt, że nie można ich przypisać, nie jest jednym z nich, więc w twoim przypadku nie jest to aspekt, który powinien zostać sprawdzony. – hvd

+0

Zrozumiałe, ale sytuacja, która wymagała ode mnie wykrycia lambda, polegała na przekazywaniu argumentu FunctionObject do argumentu typu szablonu klasy, który będzie używany jako klasa podstawowa szablonu klasy do optymalizacji pustej bazy. Ponieważ nie można dziedziczyć typu lambda w niektórych sytuacjach lub na niektórych kompilatorach. Ponieważ sytuacja się poprawia ... to nie będzie już problemem. –

Powiązane problemy