Использование параметра Boost с оператором () - PullRequest
0 голосов
/ 04 декабря 2018

Я хотел бы использовать параметр 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() здесь ...:)

Я угадывая причина в том, что Boost Parameter использует макросы и метапрограммирование для создания вспомогательных функций и т. д., и что использование функций перегрузки операторов просто невозможно.

Есть ли кто-нибудь, кто сделал что-то подобное этой работе?Это вообще возможно?

1 Ответ

0 голосов
/ 04 декабря 2018

Boost Parameter выполняет много операций конкатенации строк, поэтому ваш 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

...