C ++ 0x лямбда, как я могу передать в качестве параметра? - PullRequest
17 голосов
/ 23 июля 2010

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

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. Какого типа это должно быть?

Ответы [ 3 ]

20 голосов
/ 23 июля 2010

Преобразование в указатель на функцию является относительно новым: оно было введено с 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; });
1 голос
/ 23 июля 2010

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

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

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

0 голосов
/ 23 июля 2010

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

#include <function>

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...