V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sl0000
V2EX  ›  C++

C++大佬请看, boost::base_collection<T> 会对 T 做一个 std::is_trivial 的判断, 这个有办法做前置类型声明吗?

  •  
  •   sl0000 · 2021-07-21 15:45:31 +08:00 · 1210 次点击
    这是一个创建于 981 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在两个类需要相互引用, 直接 class B; 前置引用, is_trivial 编译失败

    // file A.hpp
    #include "B.hpp"
    class A {
    public:
        bool a = std::is_trivial_v<B>;
    };
    
    // file B.hpp
    #include "A.hpp"
    class B {
    public:
        bool a = std::is_trivial_v<A>;
    };
    
    6 条回复    2021-07-21 21:00:04 +08:00
    shylockhg
        1
    shylockhg  
       2021-07-21 16:08:06 +08:00   ❤️ 1
    不行的,前置生命只能用来定义指针
    GeruzoniAnsasu
        2
    GeruzoniAnsasu  
       2021-07-21 16:20:25 +08:00
    能再说说为什么要相互引用的情况下做这个判断吗,没有上下文感觉不到这个 trait 有什么用,A 和 B 又不是接口,除非你说 B<T>是一个静态类型分发,我想判断 B<T>的模板实例是不是 trivial 的那还能理解。
    sl0000
        3
    sl0000  
    OP
       2021-07-21 16:46:14 +08:00
    @GeruzoniAnsasu

    class A {
    public:
    boost::base_collection<B> ownBoys;
    virtual ~A() { }
    };

    class B {
    public:
    boost::base_collection<A> apples;
    virtual ~B() { }
    };

    class A1-n : public A { };
    class B1-n : public B { };
    GeruzoniAnsasu
        4
    GeruzoniAnsasu  
       2021-07-21 19:43:25 +08:00   ❤️ 1
    @sl0000
    不知道你用的哪个版本的 boost 我翻了翻文档,basic_collection 是定义在 poly_collection namespace 里的,本身就是一个多态容器,没理由要求元素是 trivial 的,猜测即使有应该也是有另一个 non poly 的实现而已,跟你这里的代码关系不大。
    而且 virtual 析构已经必不 trivial,无论如何使用的都是 poly 的版本


    再猜一下:
    1. 你想实现 A <--> B 的 many2many 映射
    2. 想用 base_collection 来放 A 或者 B,但是由于没有定义所以 base_collection 的 trait 失败了
    如果确实是这样,那么你只能换一种数据组织方式,避免相互引用直接类型,比如把对方都变成指针(这是必须的,因为你不可能在内存中造出一个“我的一部分含有全部我自己”)。
    或者干脆尝试一下其它映射比如 hasmany
    GeruzoniAnsasu
        5
    GeruzoniAnsasu  
       2021-07-21 19:53:11 +08:00   ❤️ 1
    说得不太对…… 逻辑上自指并不等于空间上会嵌套

    但 A 里的 b 和 B 里的 a 肯定要先后构造,后一个引用前一个的实例对吧。指针是 trivial 的,reference_wrapper 也可以
    sl0000
        6
    sl0000  
    OP
       2021-07-21 21:00:04 +08:00
    @GeruzoniAnsasu 你是对的,和 trivial 没关系,我仔细研究,然后重写一遍,发现是命名空间用得不对,导致 trait 失败。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3645 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 05:01 · PVG 13:01 · LAX 22:01 · JFK 01:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.