将Boost参数与operator()一起使用

时间:2018-12-04 08:24:51

标签: c++ boost operator-overloading boost-parameter

我想将Boost参数与重载的调用运算符(operator())一起使用:

#include <string>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/preprocessor.hpp>

struct add_argument_tag
{
    struct name_;
    struct descr_;
};

static inline boost::parameter::keyword<add_argument_tag::name_>&  name  = boost::parameter::keyword<add_argument_tag::name_>::get();
static inline boost::parameter::keyword<add_argument_tag::descr_>& descr = boost::parameter::keyword<add_argument_tag::descr_>::get();

struct config
{
    BOOST_PARAMETER_MEMBER_FUNCTION(
        (config),
        operator(),
        add_argument_tag,
        (required (name_, (std::string const&)))
        (optional
            (descr_, (std::string const&), "")
        )
    )
    {
        return *this;
    }
};

int main()
{
    config my_config;
    my_config
        ("foo")
        ("bar", descr = "some description");
}

不幸的是,它不起作用:

In file included from /usr/include/boost/mpl/aux_/integral_wrapper.hpp:22,
                 from /usr/include/boost/mpl/int.hpp:20,
                 from /usr/include/boost/mpl/lambda_fwd.hpp:23,
                 from /usr/include/boost/mpl/aux_/na_spec.hpp:18,
                 from /usr/include/boost/mpl/identity.hpp:17,
                 from /usr/include/boost/parameter/aux_/unwrap_cv_reference.hpp:11,
                 from /usr/include/boost/parameter/keyword.hpp:9,
                 from /.../main.cpp:2:
/.../main.cpp:18:18: error: expected unqualified-id before ')' token
         operator(),
                  ^
/.../main.cpp:18:18: error: expected unqualified-id before ')' token
         operator(),
                  ^
/.../main.cpp:18:18: error: expected unqualified-id before ')' token
         operator(),
                  ^
/.../main.cpp:16:5: error: expected nested-name-specifier before 'boost_param_result_24operator'
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /.../main.cpp:3:
/.../main.cpp:16:5: error: expected initializer before '<' token
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/mpl/aux_/integral_wrapper.hpp:22,
                 from /usr/include/boost/mpl/int.hpp:20,
                 from /usr/include/boost/mpl/lambda_fwd.hpp:23,
                 from /usr/include/boost/mpl/aux_/na_spec.hpp:18,
                 from /usr/include/boost/mpl/identity.hpp:17,
                 from /usr/include/boost/parameter/aux_/unwrap_cv_reference.hpp:11,
                 from /usr/include/boost/parameter/keyword.hpp:9,
                 from /.../main.cpp:2:
/.../main.cpp:16:5: error: expected nested-name-specifier before 'boost_param_result_24operator'
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /.../main.cpp:3:
/.../main.cpp:16:5: error: expected initializer before '<' token
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/.../main.cpp:16:5: error: 'boost_param_default_24operator' declared as function returning a function
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/.../main.cpp:16:5: error: 'boost_param_default_24operator' declared as function returning a function
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/mpl/aux_/integral_wrapper.hpp:22,
                 from /usr/include/boost/mpl/int.hpp:20,
                 from /usr/include/boost/mpl/lambda_fwd.hpp:23,
                 from /usr/include/boost/mpl/aux_/na_spec.hpp:18,
                 from /usr/include/boost/mpl/identity.hpp:17,
                 from /usr/include/boost/parameter/aux_/unwrap_cv_reference.hpp:11,
                 from /usr/include/boost/parameter/keyword.hpp:9,
                 from /.../main.cpp:2:
/.../main.cpp:16:5: error: expected nested-name-specifier before 'boost_param_result_24operator'
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /.../main.cpp:3:
/.../main.cpp:16:5: error: expected initializer before '<' token
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/.../main.cpp:16:5: error: 'boost_param_default_24operator' declared as function returning a function
     BOOST_PARAMETER_MEMBER_FUNCTION(
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/.../main.cpp: In function 'int main()':
/.../main.cpp:34:15: error: no match for call to '(config) (const char [4])'
         ("foo")
               ^
make[3]: *** [CMakeFiles/BoostParameterProblem.dir/build.make:63: CMakeFiles/BoostParameterProblem.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:73: CMakeFiles/BoostParameterProblem.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/BoostParameterProblem.dir/rule] Error 2
make: *** [Makefile:118: BoostParameterProblem] Error 2

我可以通过使用一个正确命名的函数而不是operator()来解决此问题,但是我真的会在这里使用operator() ...:)< / p>

猜测,原因是Boost Parameter如何使用宏和元编程来构造辅助函数等,而根本不可能使用运算符重载函数。

有没有人做过类似的工作?甚至有可能吗?

1 个答案:

答案 0 :(得分:2)

Boost参数确实做了很多字符串连接工作,因此您的operator()将被连接为无效名称。

一种解决方法是将operator()委派给其实现。更改宏部分以定义常规函数,然后完美转发所有参数和最终结果:

struct config
{
    BOOST_PARAMETER_MEMBER_FUNCTION(
        (config),
        myope,
        add_argument_tag,
        (required (name_, (std::string const&)))
        (optional
            (descr_, (std::string const&), "")
        )
    )
    {
        std::cout << name_ << " " << descr_ << "\n";
        return *this;
    }

    template<class... Args>
    decltype(auto) operator() (Args&& ...args) {
        return myope(std::forward<Args>(args)...);
    }
};

Live Demo