繁体   English   中英

直接重置结构的内容

[英]Reset directly the content of a struct

我已经实现了一个 function 来重置指针指向的结构的内容:

template <typename Struct>
void initialize(Struct* s)
{
    *s = Struct{};
}

Struct变大(超过 10K)时,我会遇到性能问题,因为Struct是在堆栈中创建的,然后分配给*s 我想知道我是否可以改进它:

  1. 是否可以在没有临时Struct{} object 的情况下直接初始化*s
  2. 我是否应该评估Struct的大小并将其构建在堆中(如果它很大)?

先感谢您

首先,您可能应该使用参考; 不是指针。 这样做的目的是避免 null 间接错误。

如果 class 是平凡的并且值初始化为零(这通常是大多数平凡类型的情况),那么优化器应该将您的 function 编译为对memset的调用,而无需初始化临时 ZA668CFDE691ACZF456。 所以在这种情况下应该没有理由担心。

您可以显式调用memset ,尽管从技术上讲,如果 class 包含某些类型(例如,null 指针不一定具有零表示),这在技术上不能移植到外来系统。

是否可以在没有临时 Struct{} object 的情况下直接初始化 *s?

是的,如果您愿意更改 function 的要求。 目前它适用于默认可构造和可移动分配的类。

如果直接修改指向的 object,则可以避免创建临时 object。 在以下示例中,没有创建Struct类型的临时对象:

constexpr void
initialize(Struct& s)
{
    s.member1 = T1{};
    s.member2 = T2{};

为了使其通用,可以在成员 function 中执行操作。 因此,您可以指定一个要求,即指向的 class 具有一个具有特定名称且没有参数的成员 function:

s.clear();

您可以将这两种方法组合用于它们适用的类型:

template<class Struct>
constexpr void
initialize(Struct& s)
{
    if constexpr (std::is_trivially_copyable_v<Struct>) {
        // alternative 1, if you trust your optimiser
        s = Struct{};
        // alternative 2, if you doubt the quality of the optimiser
        //    technically may have different meaning on exotic systems
        std::memset(&s, 0, sizeof s);
    } else {
        s.clear();
    }
}

如果您需要它来处理一些不符合这两个要求的类,那么您需要专门化模板。

我是否应该评估 Struct 的大小并将其构建在堆中(如果它很大 [10K])?

您通常应该避免完全拥有这么大的公共课程。 如果您需要如此大的存储空间,您可以将其包装在动态分配的类型中。 像这样的东西:

class Struct
{
private:
    struct VeryLarge{/.../};
    std::unique_ptr<VeryLarge> storage;
public:
    // public interface

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM