具有前向声明类型的 Boost.TypeErasure

Posted

技术标签:

【中文标题】具有前向声明类型的 Boost.TypeErasure【英文标题】:Boost.TypeErasure with forward declared type 【发布时间】:2015-09-01 12:49:20 【问题描述】:

最近,我尝试使用带有前向声明类型的 boost.type_erasure,如下所示:

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/member.hpp>

struct Type;

BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)

using Any = boost::type_erasure::any <
    boost::mpl::vector <
    HasTest<void(Type&)>,
    boost::type_erasure::destructible<>,
    boost::type_erasure::relaxed
    >
>;

int main() 
    Any obj;

但是,编译器(例如 clang)抱怨类型不完整:

/usr/local/include/boost/type_traits/is_base_and_derived.hpp:228:42: error: incomplete type 'Type' used in type trait expression

    BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));

最后,我必须通过将 API 从引用更改为指针来解决问题,即将 Type& 替换为 Type*。

问题:

上面的代码可以运行吗?

【问题讨论】:

【参考方案1】:

您的代码中有一些错误。首先,宏BOOST_TYPE_ERASURE_MEMBER 接受成员函数接受的参数数量的参数。所以你想要:

BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)

接下来,anyConcept 为模板,它可以是概念列表。你忘记了列表部分,所以你需要:

using Any = any<boost::mpl::vector<
    HasTest<void(Type&)>,
    relaxed
    >>;

否则,relaxed 不会包含在 Concept 中 - 这允许默认构造。接下来,您不允许在您的any 中进行破坏,因此您在~any() 上出现编译错误。您需要另外提供destructible&lt;&gt;

最后,您可以使用前向声明的类型定义您的Any。它必须由您使用的类型完成。以下编译:

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/member.hpp>

namespace mpl = boost::mpl;
using namespace boost::type_erasure;

struct Type;

BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)

using Any = any<mpl::vector<
    HasTest<void(Type&)>,
    relaxed,
    destructible<>
>>;

struct Type  ;

int main()  
    Any obj;

【讨论】:

但是你终于定义了Type...如果是指针,我就不用定义了。 @cqdjyy01234 那么使用指针?或者您可以使用 Boost 提交错误报告。无论哪种方式,您代码中的其他错误仍然存​​在。 是的,我目前确实使用指针。但是,你知道,如果引用没问题,指针不是最好的选择。感谢您指出错误。

以上是关于具有前向声明类型的 Boost.TypeErasure的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中嵌套类型/类的前向声明

前向声明 boost.type_erasure 引用类型

不完整类型的无效使用,前向声明不起作用

将前向声明的指针转换为更具体的类型

接收器类型 '' 例如消息是前向声明(但标头在 .m 中导入)

使用前向声明时如何修复“字段类型不完整”错误