宏的实际参数太多 'BOOST_FUSION_ADAPT_STRUCT_FILLER_0'

too many actual parameters for macro 'BOOST_FUSION_ADAPT_STRUCT_FILLER_0'

我正在尝试使用 boost spirit 编译一个非常简单的语法,但现在我遇到了这个编译错误,并且在花了大约一个小时试图找出原因后我希望社区中的人立即看到问题所在或者可能是。这是源代码Viper.h:

#pragma once

#include <string>
#include <vector>

#define BOOST_SPIRIT_UNICODE
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp>

namespace nsunic = boost::spirit::unicode;
namespace nsqi = boost::spirit::qi;


namespace viper
{

    struct identifier
    {
        std::wstring name;
    };

    struct identifier2
    {
        std::wstring name;
    };

    struct function
    {
        boost::variant<identifier, identifier2> func;
    };

    struct program
    {
        std::vector<function> functions;
    };
}
BOOST_FUSION_ADAPT_STRUCT(
    viper::identifier,
    (std::wstring, name)
)

BOOST_FUSION_ADAPT_STRUCT(
    viper::identifier2,
    (std::wstring, name)
)

BOOST_FUSION_ADAPT_STRUCT(
    viper::function,
    (boost::variant<viper::identifier,viper::identifier2>, func)
)

BOOST_FUSION_ADAPT_STRUCT(
    viper::program,
    (std::vector<viper::function>, functions)
)

namespace viper
{

    template<typename Iterator> struct function_parser : nsqi::grammar<Iterator, program(), nsqi::space_type>
    {
        function_parser() : function_parser::base_type(program)
        {
            identifier %=
                nsqi::eps
                >> (char_('a') > *(nsqi::alnum | nsqi::char_('_')));

            identifier2 %=
                nsqi::eps
                >> (char_('b') > *(nsqi::alnum | nsqi::char_('_')));

            function %=
                identifier | identifier2;

            program %=
                nsqi::eps
                >> +function;
        }

        nsqi::rule<Iterator, identifier()> identifier;
        nsqi::rule<Iterator, identifier2()> identifier2;
        nsqi::rule<Iterator, function(), nsqi::space_type> function;
        nsqi::rule<Iterator, program(), nsqi::space_type> program;
    };

    std::wstring render(const program& f)
    {
        std::wostringstream s;

        const auto functions_count = f.functions.size();
        for(auto j=0; j<functions_count; ++j)
        {
            if(j>0)
            {
                s << L",";
            }
            s << f.functions[j].name;
        }
        return s.str();
    }

    template<typename Iterator> std::wstring parse(Iterator first, Iterator last)
    {
        using nsqi::phrase_parse;

        program f;
        function_parser<Iterator> fp;

        auto b = phrase_parse(first, last, fp, nsqi::space, f);
        if(b)
        {
            return render(f);
        }
        return std::wstring(L"FAIL");
    }

}

编译器的输出是这样的:

1>------ Build started: Project: Viper.Notepad, Configuration: Debug Win32 ------
1>Build started 24-Jan-16 17:40:29.
1>InitializeBuildStatus:
1>  Touching "Debug\Viper.Notepad.unsuccessfulbuild".
1>ClCompile:
1>  All outputs are up-to-date.
1>  Viper.Notepad.cpp
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): warning C4002: too many actual parameters for macro 'BOOST_FUSION_ADAPT_STRUCT_FILLER_0'
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2146: syntax error : missing ',' before identifier 'attribute_type'
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2065: 'attribute_type' : undeclared identifier
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2143: syntax error : missing '>' before ';'
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2208: 'boost::variant' : no members defined using this type
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:23.25
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

第 51 行是第 3 个 BOOST_FUSION_ADAPT_STRUCT() 宏的结尾 ')'。

问题是 boost::variant<viper::identifier,viper::identifier2> 包含一个逗号 (,),因此被预处理器解释为 2 个参数。

解决方法:

typedef boost::variant<viper::identifier,viper::identifier2> Variant; 
BOOST_FUSION_ADAPT_STRUCT(
    viper::function,
    (Variant, func)
)

列出了其他一些解决方法