C++小實驗:在C++中實現類似於動態語言函數定義的宏

編譯需要開啓C++14支持

Code

// fun.h

#include<boost/preprocessor.hpp>

#define SIZE(...) BOOST_PP_TUPLE_SIZE((__VA_ARGS__))

#define _CAT(a, b) a##b
#define CAT(a, b) _CAT(a, b)

#define _STRING(a) #a
#define STRING(a) _STRING(a)

#define OP_HEAD(d, state, x) \
    (BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(2, 0, state), 1), \
     BOOST_PP_LIST_CONS(typename CAT(_, BOOST_PP_TUPLE_ELEM(2, 0, state)), BOOST_PP_TUPLE_ELEM(2, 1, state)))

#define OP_BODY(d, state, x) \
    (BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(2, 0, state), 1), \
     BOOST_PP_LIST_CONS(CAT(_, BOOST_PP_TUPLE_ELEM(2, 0, state)) x, BOOST_PP_TUPLE_ELEM(2, 1, state)))

#define FUN_HEAD(...) \
    template<BOOST_PP_REMOVE_PARENS( \
        BOOST_PP_LIST_TO_TUPLE( \
            BOOST_PP_TUPLE_ELEM(2, 1, \
                BOOST_PP_LIST_FOLD_RIGHT(OP_HEAD, (SIZE(__VA_ARGS__), BOOST_PP_LIST_NIL), \
                    BOOST_PP_TUPLE_TO_LIST((__VA_ARGS__))))))>

#define FUN_BODY(...) \
    BOOST_PP_LIST_TO_TUPLE( \
        BOOST_PP_TUPLE_ELEM(2, 1, \
            BOOST_PP_LIST_FOLD_RIGHT(OP_BODY, (SIZE(__VA_ARGS__), BOOST_PP_LIST_NIL), \
                BOOST_PP_TUPLE_TO_LIST((__VA_ARGS__)))))

#define FUN(f, ...) \
    FUN_HEAD(__VA_ARGS__) auto f FUN_BODY(__VA_ARGS__)

// test.cpp

#include <iostream>
#include "fun.h"

namespace test {

FUN(plus, a, b) {
    return a + b;
}

FUN(push, &a, b) {
    a.push_back(b);
}

}

int main(int argc, char **argv) {
    // test plus
    std::cout << test::plus(1, 2) << std::endl;
    // test push
    std::vector<int> v {1, 2, 3};
    test::push(v, 4);
    for (auto & i : v) std::cout << i << ' ';
    std::cout << std::endl;
    return 0;
}

Result

3
1 2 3 4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章