SORU
30 EKİM 2011, Pazar


Parametre türü anlamaya ve lambda tipi dönüş mümkün mü?

Lambda verilen, bu parametre türünü anlamaya ve yazın geri dönmek mümkün mü? Evet ise, nasıl?

Temel olarak, aşağıdaki şekillerde kullanılabilir lambda_traits istiyorum:

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

lambda_traits<decltype(lambda)>::param_type  i; //i should be int
lambda_traits<decltype(lambda)>::return_type l; //l should be long

Motivasyon arkasında argüman olarak bir lambda kabul eden bir işlev şablonu lambda_traits kullanmak istiyorum ve bu parametre türü olduğunu ve bu işlev içinde yazın geri dönmek istiyorum:

template<typename TLambda>
void f(TLambda lambda)
{
   typedef typename lambda_traits<TLambda>::param_type  P;
   typedef typename lambda_traits<TLambda>::return_type R;

   std::function<R(P)> fun = lambda; //I want to do this!
   //...
}

Şimdilik, lambda tam olarak bir argüman alır varsayabiliriz.

Başlangıçta, std::function olarak birlikte çalışmaya çalıştım:

template<typename T>
A<T> f(std::function<bool(T)> fun)
{
   return A<T>(fun);
}

f([](int){return true;}); //error

Ama belli ki hata (ideone) verecek. İşlev şablon TLambda sürüm değiştirdim ve işlev içinde std::function nesne oluşturmak için (yukarıda gösterildiği gibi).

CEVAP
30 EKİM 2011, Pazar


Komik, sadece function_traits implementation dayanarak yazdım . ben^>Specializing a template on a lambda in C 0xparametre türleri verebilir. Bu soruya cevap olarak açıklandığı gibi sizi operator() lambda decltype kullanmaktır.

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
{
    enum { arity = sizeof...(Args) };
    // arity is the number of arguments.

    typedef ReturnType result_type;

    template <size_t i>
    struct arg
    {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
        // the i-th argument is equivalent to the i-th tuple element of a tuple
        // composed of those arguments.
    };
};

// test code below:
int main()
{
    auto lambda = [](int i) { return long(i*10); };

    typedef function_traits<decltype(lambda)> traits;

    static_assert(std::is_same<long, traits::result_type>::value, "err");
    static_assert(std::is_same<int, traits::arg<0>::type>::value, "err");

    return 0;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AutoklubZAPRESIC

    AutoklubZAPR

    17 Mayıs 2011
  • CMTelly

    CMTelly

    2 Mayıs 2007
  • LiteralMSPaint

    LiteralMSPai

    27 EKİM 2010