c++ 从boost::spirit::qi::grammar编译派生类失败,错误为__declspec(dllexport)

r3i60tvu  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(96)

我正在尝试实现一个继承自boost::spirit::qi::grammar的类,并使其可在动态库中导出:

#pragma once
#include <impexp.h>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

using boost::spirit::ascii::space_type;
struct EXPORT_DLLCLASS Grammar : boost::spirit::qi::grammar< char const*, space_type >
{
   Grammar()
       : Grammar::base_type( expr )
   {
   }
   boost::spirit::qi::rule< char const*, space_type > expr, term;
};

我使用EXPORT_DLLCLASS来指定__attribute__( ( visibility( "default" ) ) )__declspec( dllexport ),具体取决于平台。在Linux平台下构建成功,但在Windows平台下编译时遇到问题,错误如下:

C:\.conan\oq2odq\1\include\boost/proto/extends.hpp(536,17):  error: call to implicitly-deleted default constructor of 'boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0>'
              : proto_expr_()
                ^
C:\.conan\oq2odq\1\include\boost/proto/proto_fwd.hpp(377,16):  note: in instantiation of member function 'boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0>, boost::spirit::qi::grammar<const char *, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>, boost::proto::domainns_::default_domain, 0>::extends' requested here
        struct extends;
               ^
C:\.conan\oq2odq\1\include\boost/proto/detail/preprocessed/expr_variadic.hpp(50,49):  note: default constructor of 'expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0>' is implicitly deleted because field 'child0' has no default constructor
        typedef Arg0 proto_child0; proto_child0 child0;

如果未指定EXPORT_DLLCLASS,则构建成功。

vkc1a9a2

vkc1a9a21#

已确认,请与MSVC 19.34.31931 x64(和GCC)一起查看,尽管https://compiler-explorer.com/z/o67TYxdnf上的诊断略有不同:

C:/data/libraries/installed/x64-windows/include\boost/proto/extends.hpp(558): error C2440: 'return': cannot convert from 'T *' to 'boost::proto::detail::not_a_valid_type'
        with
        [
            T=const boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>>
        ]
C:/data/libraries/installed/x64-windows/include\boost/proto/extends.hpp(558): note: No constructor could take the source type, or constructor overload resolution was ambiguous
C:/data/libraries/installed/x64-windows/include\boost/proto/extends.hpp(558): note: while compiling class template member function 'boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>,boost::spirit::qi::grammar<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>,boost::proto::domainns_::default_domain,0>::operator boost::proto::detail::not_a_valid_type(void) const'
        with
        [
            T=boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>>
        ]
C:/data/libraries/installed/x64-windows/include\boost/spirit/home/qi/nonterminal/grammar.hpp(32): note: see reference to class template instantiation 'boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>,boost::spirit::qi::grammar<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>,boost::proto::domainns_::default_domain,0>' being compiled
        with
        [
            T=boost::spirit::qi::reference<const boost::spirit::qi::rule<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>>
        ]
<source>(6): note: see reference to class template instantiation 'boost::spirit::qi::grammar<const char *,boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>' being compiled
Compiler returned: 2

我认为这可能是一个编译器问题。我会向Boost Proto维护人员报告:https://github.com/boostorg/proto/issues,以查看他们是否可以确认或建议解决方法

相关问题