【问题标题】:SFINAE to disable POD structure with pointers in C++SFINAE 在 C++ 中使用指针禁用 POD 结构
【发布时间】:2021-11-16 15:30:55
【问题描述】:

我正在寻找解决方案来禁用模板参数结构,这些结构是 POD(或说可复制)但具有指针。我将通过网络发送它们。例如

// good
struct S1 {
    int x;
    S1() : x( 42 ) {} // I know that it's not a POD, but I know, that I can send S1 over network
};
// bad
struct S2 {
    int *x;
};

template<typename POD>
class ToNetwork {
    //static_assert( std::is_trivially_copyable< POD >::value, "Type must be POD" );
    static_assert( std::is_standard_layout< POD >::value, "Type must be POD" );
    POD m_payload;
};
ToNetwork< S1 > s1;
ToNetwork< S2 > s2; // should fail, but not((

is_trivially_copyableis_standard_layout 都说这两种结构都很好。

【问题讨论】:

  • 不确定这是否可以自动检测。假设您有一个struct S3 { some_iterator_type it; }。或struct S4 { size_t index_into_some_container; };
  • 这可能会有所帮助:stackoverflow.com/questions/17660095/…
  • 请注意,您通常必须单独处理每个成员(至少要处理字节序),因此无论如何您都不能简单地 memcpy 结构。
  • @Jarod42 我有一个template&lt;typename POD&gt; 并想memcpy 它。我不知道POD的成员
  • @463035818_is_not_a_number 我看到了 MSVC 对 iterator 的实现——它有指针。这就是为什么如果我能找到解决方案,那么迭代器就不会成为问题。如果我发送静态数组([42])并在其中索引对我有好处

标签: c++ sfinae


【解决方案1】:

这部分是一个框架挑战答案:要正确序列化某些东西,无论如何只有非指针平凡成员是不够的。

即使您目前只与同一平台上的同行交谈,这也很脆弱(即,当有人想要连接 ARM/RISC/M1/其他设备时,您必须记录您的字节顺序和数据大小)。

此外,内存和在线类型的填充和对齐要求很少一致。您最终倾向于逐个成员(反)序列化,或者编写一个压缩/未对齐的覆盖结构,这对于内存使用效率较低(并且也是不可移植的)。

这意味着在实践中,您将声明用于通过网络发送的专用类型——要么具有自己的(反)序列化方法,要么具有一些元数据,要么具有__attribute__((packed)),或其他类型。由于他们致力于此,因此给他们一个成员或嵌套类型供您的 SFINAE 直接检测是微不足道的。

【讨论】:

  • 我确实有一个库(我们团队内部的),通过这种结构(超过 300 种类型)通过网络进行交换。该库成功地使用了来自问题的ToNetwork 之类的模板。我保证平台是一样的。我只是想将此模板修改为进一步的结构,以免在我的腿上射击))
  • 我不认为有办法直接做到这一点,所以你只需要在代码审查或测试中抓住它。超过 300 种自定义消息类型很多!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 2019-03-27
  • 2021-03-28
  • 1970-01-01
  • 2020-08-19
  • 2018-11-03
  • 1970-01-01
相关资源
最近更新 更多