C++03 中的 Lambda
Lambdas in C++03
因此,我正在尝试替换以下代码 (C++11):
struct test {
const char *n;
int i;
std::function<int(void)> read;
std::function<void(int)> write;
};
#define define_test(n, i, bodyRead, bodyWrite) \
{ n, i, []() { bodyRead; }, [](int v) { bodyWrite; } }
std::initializer_list<test> tests = {
define_test("test1", 1, return 1, v = 2),
...
};
使用具有相同效果的 C++03 兼容代码:
struct test {
test(const char *_n, int _i, boost::function<int(void)> _read, boost::function<void(int)> _write) {
n = _n;
i = _i;
read = _read;
write = _write;
}
const char *n;
int i;
boost::function<int(void)> read;
boost::function<void(int)> write;
};
#define define_test(n, i, bodyRead, bodyWrite) \
( n, i, []() { bodyRead; }, [](int v) { bodyWrite; } )
std::vector<test> tests;
static void init_tests(void) {
tests.push_back(define_test("test1", 1, return 1, v = 2));
}
毫无疑问,Visual C++ Studio 2008 Express SP1 编译器拒绝 lambda 表达式,使用 boost 也无济于事,除了 bind() 和 lambda boost 得到了,我不太确定我是怎么做到的会用这个来做。
为了更详细地说明这一点,我希望也能够像这样使用:
using namespace boost::assign;
static std::vector<test> tests;
static void init_tests(void) {
push_back(tests)
define_test(...)
...;
}
这意味着具有静态函数的结构也不会有太大帮助,例如:
#define define_test(n, i, bodyRead, bodyWrite) \
struct {
static void fn##n(void) { bodyRead; } \
static void fnw##n(int v) { bodyWrite; } \
}; \
( n, i, boost::bind(&fn##n), boost::bind(&fnw##n, boost::placeholders::_1) )
那是因为我写了很多这样的东西,而 C++11 是如此简单。
例如,您可以使用 Boost Phoenix 拼凑一些东西。
s_tests.push_back(test ( "test1", 1, phx::val(1), phx::ref(v) = arg1*1 ));
s_tests.push_back(test ( "test2", 2, phx::val(2), phx::ref(v) = arg1*2 ));
它不会实现自然的 C++ 语法,但至少它的功能非常齐全(它支持异常、while_、for_、switch_、locals、bind() 等):
#include <boost/function.hpp>
struct test {
const char *n;
int i;
boost::function<int(void)> read;
boost::function<void(int)> write;
test(char const* n, int i, boost::function<int(void)> read, boost::function<void(int)> write)
: n(n), i(i), read(read), write(write)
{}
};
#include <boost/phoenix.hpp>
#include <vector>
using namespace boost::phoenix::arg_names;
namespace phx = boost::phoenix;
namespace mocks {
static int v;
typedef std::vector<test> test_t;
test_t const& tests() {
static test_t s_tests;
if (s_tests.empty())
{
s_tests.push_back(test ( "test1", 1, phx::val(1), phx::ref(v) = arg1*1 ));
s_tests.push_back(test ( "test2", 2, phx::val(2), phx::ref(v) = arg1*2 ));
}
return s_tests;
}
}
#include <iostream>
int main() {
for (mocks::test_t::const_iterator it = mocks::tests().begin();
it != mocks::tests().end(); ++it)
{
test const& test = *it;
std::cout << "'" << test.n << "'\t" << test.i << ", " << test.read() << ", ";
test.write(42);
std::cout << "mock v: " << mocks::v << "\n";
}
}
版画
'test1' 1, 1, mock v: 42
'test2' 2, 2, mock v: 84
因此,我正在尝试替换以下代码 (C++11):
struct test {
const char *n;
int i;
std::function<int(void)> read;
std::function<void(int)> write;
};
#define define_test(n, i, bodyRead, bodyWrite) \
{ n, i, []() { bodyRead; }, [](int v) { bodyWrite; } }
std::initializer_list<test> tests = {
define_test("test1", 1, return 1, v = 2),
...
};
使用具有相同效果的 C++03 兼容代码:
struct test {
test(const char *_n, int _i, boost::function<int(void)> _read, boost::function<void(int)> _write) {
n = _n;
i = _i;
read = _read;
write = _write;
}
const char *n;
int i;
boost::function<int(void)> read;
boost::function<void(int)> write;
};
#define define_test(n, i, bodyRead, bodyWrite) \
( n, i, []() { bodyRead; }, [](int v) { bodyWrite; } )
std::vector<test> tests;
static void init_tests(void) {
tests.push_back(define_test("test1", 1, return 1, v = 2));
}
毫无疑问,Visual C++ Studio 2008 Express SP1 编译器拒绝 lambda 表达式,使用 boost 也无济于事,除了 bind() 和 lambda boost 得到了,我不太确定我是怎么做到的会用这个来做。
为了更详细地说明这一点,我希望也能够像这样使用:
using namespace boost::assign;
static std::vector<test> tests;
static void init_tests(void) {
push_back(tests)
define_test(...)
...;
}
这意味着具有静态函数的结构也不会有太大帮助,例如:
#define define_test(n, i, bodyRead, bodyWrite) \
struct {
static void fn##n(void) { bodyRead; } \
static void fnw##n(int v) { bodyWrite; } \
}; \
( n, i, boost::bind(&fn##n), boost::bind(&fnw##n, boost::placeholders::_1) )
那是因为我写了很多这样的东西,而 C++11 是如此简单。
例如,您可以使用 Boost Phoenix 拼凑一些东西。
s_tests.push_back(test ( "test1", 1, phx::val(1), phx::ref(v) = arg1*1 ));
s_tests.push_back(test ( "test2", 2, phx::val(2), phx::ref(v) = arg1*2 ));
它不会实现自然的 C++ 语法,但至少它的功能非常齐全(它支持异常、while_、for_、switch_、locals、bind() 等):
#include <boost/function.hpp>
struct test {
const char *n;
int i;
boost::function<int(void)> read;
boost::function<void(int)> write;
test(char const* n, int i, boost::function<int(void)> read, boost::function<void(int)> write)
: n(n), i(i), read(read), write(write)
{}
};
#include <boost/phoenix.hpp>
#include <vector>
using namespace boost::phoenix::arg_names;
namespace phx = boost::phoenix;
namespace mocks {
static int v;
typedef std::vector<test> test_t;
test_t const& tests() {
static test_t s_tests;
if (s_tests.empty())
{
s_tests.push_back(test ( "test1", 1, phx::val(1), phx::ref(v) = arg1*1 ));
s_tests.push_back(test ( "test2", 2, phx::val(2), phx::ref(v) = arg1*2 ));
}
return s_tests;
}
}
#include <iostream>
int main() {
for (mocks::test_t::const_iterator it = mocks::tests().begin();
it != mocks::tests().end(); ++it)
{
test const& test = *it;
std::cout << "'" << test.n << "'\t" << test.i << ", " << test.read() << ", ";
test.write(42);
std::cout << "mock v: " << mocks::v << "\n";
}
}
版画
'test1' 1, 1, mock v: 42
'test2' 2, 2, mock v: 84