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

2021-07-21 15:45:31 +08:00
 sl0000

现在两个类需要相互引用, 直接 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>;
};
1341 次点击
所在节点    C++
6 条回复
shylockhg
2021-07-21 16:08:06 +08:00
不行的,前置生命只能用来定义指针
GeruzoniAnsasu
2021-07-21 16:20:25 +08:00
能再说说为什么要相互引用的情况下做这个判断吗,没有上下文感觉不到这个 trait 有什么用,A 和 B 又不是接口,除非你说 B<T>是一个静态类型分发,我想判断 B<T>的模板实例是不是 trivial 的那还能理解。
sl0000
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
2021-07-21 19:43:25 +08:00
@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
2021-07-21 19:53:11 +08:00
说得不太对…… 逻辑上自指并不等于空间上会嵌套

但 A 里的 b 和 B 里的 a 肯定要先后构造,后一个引用前一个的实例对吧。指针是 trivial 的,reference_wrapper 也可以
sl0000
2021-07-21 21:00:04 +08:00
@GeruzoniAnsasu 你是对的,和 trivial 没关系,我仔细研究,然后重写一遍,发现是命名空间用得不对,导致 trait 失败。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/790854

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX