Lambard in C ++ 03

时间:2015-02-05 16:48:11

标签: c++ c++11 boost lambda 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很容易。

1 个答案:

答案 0 :(得分:4)

例如,你可以和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()等。):

<强> Live On Coliru

#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