Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在什么情况下,我们需要知道一个类是否微不足道?_C++_Class_C++11_Typetraits - Fatal编程技术网

C++ 在什么情况下,我们需要知道一个类是否微不足道?

C++ 在什么情况下,我们需要知道一个类是否微不足道?,c++,class,c++11,typetraits,C++,Class,C++11,Typetraits,std::is_trival::value可以确定类T是否微不足道。然而,我想不出一个场景需要这些信息 有什么例子吗 我的一些想法: 假设T类很小,是否意味着T可以通过memcpy这样安全地复制: T t1, t2; memcpy(&t1, &t2, sizeof(T)); ?例如,如果某个类型很普通,可以使用memcpy复制该类型。这是作为std::atomic模板参数使用的用户定义类型的要求。也就是说,对于用户定义的类型T,atomic允许(并且对于较大的类型,需要)使用m

std::is_trival::value
可以确定类T是否微不足道。然而,我想不出一个场景需要这些信息

有什么例子吗

我的一些想法:

假设T类很小,是否意味着T可以通过
memcpy
这样安全地复制:

T t1, t2;
memcpy(&t1, &t2, sizeof(T));

例如,如果某个类型很普通,可以使用
memcpy
复制该类型。这是作为
std::atomic
模板参数使用的用户定义类型的要求。也就是说,对于用户定义的类型
T
atomic
允许(并且对于较大的类型,需要)使用
memcpy
实现从
T
类型的对象到
atomic
类型的对象的赋值。类似地,在需要时,使用
memcmp
进行相等性测试


< >使用这些C函数而不是C++运算符的原因是,原子操作不调用任何用户代码。这样做可能会导致看似无辜的代码出现神秘的死锁。

实际上,普通类型对于只需要字符指针和长度的/anywhere/非常有用。Pete Becker的回答描述了这个重要的案例,但这里有一点很愚蠢:您可以使用
std::ostream::write
序列化一个普通类型,然后使用
std::istream::read
将其读回

template<typename T>
std::enable_if<std::is_trivial<T>, void> 
bin_write(std::ostream& out, const T& data) {
  out.write(reinterpret_cast<const char*>(&data), sizeof(T));
}

template<typename T>
std::enable_if<std::is_trivial<T>::value, T> 
bin_read(std::istream& in) {
  using T_in = std::remove_cv_t<T>; //even if T is const, the buffer can't be
  T_ buffer;
  in.read(reinterpret_cast<char*>(&buffer), sizeof(T_));
  return buffer;
}
模板
std::启用_if
bin_写入(标准::ostream&out、const T&data){
out.write(重新解释铸件和数据),sizeof(T));
}
模板
std::启用_if
bin_读取(标准::istream&in){
使用T_in=std::remove_cv_T;//即使T是const,也不能删除缓冲区
缓冲区;
in.read(reinterpret_cast(&buffer),sizeof(T_));
返回缓冲区;
}

显然,您不能在原始指针(或原始指针包装器,例如,
std::experimental::observer_ptr
)上使用此选项。这会忽略endianness,所以您可能不想将此数据发送到其他计算机上的其他应用程序。但是,如果您想编写模拟重新启动文件,或者如果需要在GCC编译的C++和GCC编译的FORTRAN。/P>之间传输数据,请看一下,我会搜索标准的“琐碎”,并检查什么解释涉及到这个概念。一下子我想不出有什么特别的用途,因为琐碎的复制是一个更基本的特性。另一件事是,普通类型不需要调用它们的析构函数,这可以提高std::vector的效率。所以这不仅是安全,而且是简单的效率。@Xeo-true,但我不认为这回答了被问到的问题,即“我什么时候需要知道这个”?嗯,仔细想想,我的也没有回答这个问题:如果你定义一个原子类型,你可能知道你的类型很简单,不需要类型特征来告诉你。我认为它很好地回答了这个问题——“我什么时候需要知道这个?”——“当你想写尽可能高性能的代码时”以及“当特殊需求使非平凡类型成为不可能”你可以说它(像C++的许多部分一样)只对库编写者有用,但是,呃……将平凡类型与
std::memcmp()进行比较只允许在不正确的非相等的情况下使用< /COD>。它是由于非规范表示而发生的,例如,对浮点和填充进行了查找。为了澄清:FORTRAN有点老了,并且没有与C或C++相同的标准化级别,所以在序列化和反序列化方面,您的保证更少。FORTRAN标准库或其内置操作符。结果是C++中的特征类似于STD::Is平凡,并且所有标准中的保证都是绝对神圣的。