C++ 0x лямбда, как я могу передать в качестве параметра?

Посмотрите на следующий C++ 0x связанный с лямбдой код:

typedef uint64_t (*WEIGHT_FUNC)(void* param);
typedef std::map<std::string, WEIGHT_FUNC> CallbackTable;

CallbackTable table;
table["rand_weight"] = [](void* param) -> uint64_t
{
  return (rand() % 100 + 1);
};

Я получил ошибку (в Visual Studio 2010), из которого лямбда не могла быть преобразована в тип WEIGHT_FUNC. Я также знаю ответ: использование std::function object:

typedef std::function<uint64_t (void*)>  WEIGHT_FUNC;

Однако я также хочу знать, как я могу получить тип лямбды БЕЗ использования std::function. Каково тип это должно быть?

17
задан minjang 23 July 2010 в 22:56
поделиться

3 ответа

Преобразование в указатель на функцию является относительно новым: оно было введено в N3043 15 февраля 2010 г.

Хотя, например, GCC 4.5 реализует его, Visual Studio 10 была выпущена 12 апреля 2010 года и поэтому просто не реализовала его вовремя. Как указал Джеймс, эта будет исправлена ​​ в будущих выпусках.

На данный момент вам нужно использовать одно из альтернативных решений, представленных здесь.

Технически что-то вроде следующего обходного пути будет работать, но без вариативных шаблонов его неинтересно обобщать (Boost.PP спешит на помощь ...), и нет защиты от передачи лямбда-выражений в:

typedef uint64_t (*WeightFunc)(void* param);

template<class Func> WeightFunc make_function_pointer(Func& f) {
    return lambda_wrapper<Func>::get_function_pointer(f);
}

template<class F> class lambda_wrapper {
    static F* func_;
    static uint64_t func(void* p) { return (*func_)(p); }    
    friend WeightFunc make_function_pointer<>(F& f);    
    static WeightFunc get_function_pointer(F& f) {
        if (!func_) func_ = new F(f);
        return func;
    }
};

template<class F> F* lambda_wrapper<F>::func_ = 0;

// ...
WeightFunc fp = make_function_pointer([](void* param) -> uint64_t { return 0; });
20
ответ дан 30 November 2019 в 13:45
поделиться

Если вы действительно настаиваете на том, чтобы не использовать function <> , тогда вы, вероятно, могли бы использовать decltype:

typedef decltype([](void*)->uint_64{return 0;}) my_lambda_type;

Я действительно не рекомендую этого, поскольку вы резко ограничиваете себя, а я даже не знать, гарантированно ли два лямбда с одинаковой сигнатурой будут одного и того же типа.

1
ответ дан 30 November 2019 в 13:45
поделиться

Попробуйте с (не проверено) :

#include <function>

typedef std::function< int64_t (void*) > weight_func;
typedef std::map<std::string, weight_func > CallbackTable;

Я не думаю, что есть другой способ сделать это, кроме как использовать std::function или эквивалент.

-1
ответ дан 30 November 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: