4

x3 のドキュメント ( http://ciere.com/cppnow15/x3_docs/spirit/tutorials/rexpr.html )の例を適用して、単純なバイナリ プレフィックス表記の文法を解析したところ、コピー コンを定義する必要があることがわかりました。のコンストラクbase_typeターと代入演算子をusing. 次に、 clang 3.8.1 で期待どおりにコンパイルされるという事実に遭遇しました。コードの重要な部分を投稿します。エラーを示す AST プリンターを使用したg++ の完全な例を次に示します。

g++ は、move コンストラクターまたは move 代入演算子が定義されているため、コピー コンが削除されたと考えているようですが、なぜ clang でコンパイルされるのでしょうか。どのコンパイラが正しいですか?

#include <iostream>
#include <string>
#include <vector>

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

namespace x3 = boost::spirit::x3;
namespace chars = boost::spirit::x3::ascii;

namespace ast {

    struct Expression;

    struct Primary : x3::variant<
        std::string,
        x3::forward_ast<Expression>
    > {
        // GCC seems to require these three to be defined, but clang doesn't
        // if I comment them out, then it compiles on clang but not gcc
        Primary& operator=(const Primary&) = default;
        Primary(const Primary&) = default;
        Primary() = default;

        // the documentation says that only these two are necessary
        using base_type::base_type;
        using base_type::operator=;
    };

    using ArgumentList = std::vector<Primary>;

    struct Expression {
        std::string func_name;
        ArgumentList arguments;
        Expression() : func_name(), arguments() { }
    };

}

BOOST_FUSION_ADAPT_STRUCT(
    ast::Expression,
    func_name,
    arguments
)

namespace parser {
    x3::rule<class Primary,      ast::Primary     > Primary      = "Primary";
    x3::rule<class Expression,   ast::Expression  > Expression   = "Expression";

    const auto function_name = x3::lexeme[ +chars::alnum ];
    const auto number = x3::lexeme[ +chars::digit ];
    const auto Primary_def = number | Expression;
    const auto Expression_def = function_name > x3::repeat(2)[ Primary ]; // only accept binary functions for now

    BOOST_SPIRIT_DEFINE(Primary, Expression)
}

int main() {

    while (std::cin.good() == true) {

        const auto line = [&]() {
            std::string str;
            std::getline(std::cin, str);
            return str;
        }();
        auto iter_in_line = begin(line);
        const auto end_of_line = end(line);

        ast::Expression root_expr;

        const bool is_match = phrase_parse(iter_in_line, end_of_line,
            parser::Expression,
            chars::space,
            root_expr
        );
    }
}
4

0 に答える 0