Давайте рассмотрим следующий пример:Инициализация класса с лямбда передается в конструктор, C++ 11
#include <functional>
#include <iostream>
using namespace std;
class Caller {
public:
Caller(function<void()> callback) {
callback();
}
};
main() {
#if defined(ONELINER)
Caller caller = [] { cout << "test"; };
#else
function<void()> fun = [] { cout << "test"; };
Caller caller(fun);
#endif // defined(ONELINER)
}
Если мы просто попытаться скомпилировать его (с -std = C++ 11 флагу) будет счастливо закончить , и показ test
при запуске. Однако, если мы определим ONELINER
макрос компиляции будет завершаться:
prog.cpp: In function 'int main()':
prog.cpp:17:40: error: conversion from 'main()::<lambda()>' to non-scalar type 'Caller' requested
Caller caller = [] { cout << "test"; };
Я понимаю, что это вызвано тем, что существует неявное преобразование из лямбда в std::function
, а затем неявное преобразование из std::function
в Caller
, и мы не можем выполнить 2 конверсии одновременно.
Возможно ли сделать синтаксис Class object = lambda;
? Я спрашиваю, потому что я играл в последнее время с написанием собственной небольшой рамки тестирования для образовательных целей, и я подумал, что это:
UNIT_TEST(test_name) {
// test content
};
гораздо более элегантно, чем
UNIT_TEST_BEGIN(test_name)
// unit test
UNIT_TEST_END()
Первого может быть достигнута с лямбдой передается в конструктор UnitTest
. Но проблема, которую я описал, я должен был использовать грязные обходной путь, как:
#define UNIT_TEST(test_name) \
::std::function<void(::Helper*)> test_name_helper; \
::UnitTest test_name ## _test = \
test_name_helper = \
[&] (::Helper* helper)
и не выглядеть элегантно на всех. Но даже если это можно сделать без lambdas, я все еще заинтригован, может ли быть достигнут синтаксис Class object = lamda;
.
Большинство стандартных функций с вызываемым аргументом используют * шаблоны *. –
Не могли бы вы немного разобраться? 'std :: function' является шаблоном, так что, полагаю, у вас есть конкретный случай использования? –