gpt4 book ai didi

c++ - 在构造函数之后运行的初始化 block

转载 作者:行者123 更新时间:2023-12-05 05:45:33 27 4
gpt4 key购买 nike

假设我有以下类(class):

template <class Base>
struct Wrapper : public Base {
using Base::Base;

// ... add functionality ...
};

而且我希望在构造函数之后的构造过程中执行一些代码。我无法添加默认构造函数,因为在使用继承的构造函数时它不会运行。一个想法是这样的:

template <class Base>
struct Wrapper : public Base {
bool _ = [this] {
// initialize ...
return true;
}();

using Base::Base;
};

只要您将它作为最后一个成员放置,它就可以很好地工作,但它会浪费内存。

另一种方式是:

#include <type_traits>

template <class T>
struct InitBlock {
InitBlock() {
static_cast<T*>(this)->init();
}
};

template <class Base>
struct Wrapper : public Base, private InitBlock<Wrapper<Base>> {
private:
template <class T>
friend struct InitBlock;

void init() {
// initialize ...
}

public:
using Base::Base;
};

这很好,但有点冗长。并且没有任何东西可以保护 init 不被其他地方再次调用。此外,如果 Wrapper 添加成员,这将在那些被初始化之前被调用,所以它并不理想。

执行此操作的更好(安全且样板代码少)方法是什么?

最佳答案

As mentioned ,我们可以使用 [[no_unique_address]] 来避免为空类分配内存。除 MSVC 外,所有主要编译器都支持它。 MSVC 有自己的扩展名 [[msvc::no_unique_address]]。我们围绕它包装一个宏,它工作正常:

#include <stdio.h>

#ifdef _MSC_VER
#define NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#else
#define NO_UNIQUE_ADDRESS [[no_unique_address]]
#endif

template <class Base>
struct Wrapper : public Base {
private:
NO_UNIQUE_ADDRESS struct Init {} _ = [] {
puts("Wrapper init");
return Init{};
}();
public:
using Base::Base;
};


struct Foo {
int i;

Foo(int i) : i(i) {
printf("Foo(%d)\n", i);
}
};

int main() {
Wrapper<Foo> wfoo(42);
Foo foo(43);
static_assert(sizeof(wfoo) == sizeof(foo));
}

您仍然需要注意将它放在所有其他成员之后,以确保在我们接触它们时它们已被初始化,所以这并不理想。

See online

关于c++ - 在构造函数之后运行的初始化 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71333871/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com