使用传入构造函数的 lambda 初始化 class,C++11
Initializing class with a lambda passed into constructor, 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"; };
我理解这是由于lambda到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()
前者可以通过将 lambda 传递给 UnitTest
构造函数来实现。但是对于我描述的问题,我不得不使用肮脏的解决方法,例如:
#define UNIT_TEST(test_name) \
::std::function<void(::Helper*)> test_name_helper; \
::UnitTest test_name ## _test = \
test_name_helper = \
[&] (::Helper* helper)
而且看起来一点也不优雅。但即使这可以在没有 lambda 的情况下完成,我仍然很好奇是否可以实现 Class object = lamda;
语法。
修改构造函数为:
template<typename CB>
Caller(CB callback) {
callback();
}
这将允许它接受 任何 可调用参数,无论是 lambda、std::function
、函数指针还是仿函数。
不幸的是,构造函数也将接受任何 other 类型,但是当 callback
不能像函数一样 "called" 时给出编译器错误.
让我们考虑以下示例:
#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"; };
我理解这是由于lambda到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()
前者可以通过将 lambda 传递给 UnitTest
构造函数来实现。但是对于我描述的问题,我不得不使用肮脏的解决方法,例如:
#define UNIT_TEST(test_name) \
::std::function<void(::Helper*)> test_name_helper; \
::UnitTest test_name ## _test = \
test_name_helper = \
[&] (::Helper* helper)
而且看起来一点也不优雅。但即使这可以在没有 lambda 的情况下完成,我仍然很好奇是否可以实现 Class object = lamda;
语法。
修改构造函数为:
template<typename CB>
Caller(CB callback) {
callback();
}
这将允许它接受 任何 可调用参数,无论是 lambda、std::function
、函数指针还是仿函数。
不幸的是,构造函数也将接受任何 other 类型,但是当 callback
不能像函数一样 "called" 时给出编译器错误.