gpt4 book ai didi

c++ - 在 C++ 中,如何在不使用 new 且不单独声明单个元素的情况下创建 `std::initializer_list`?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:03:39 34 4
gpt4 key购买 nike

在 C++ 中,您可以在文件范围内声明一个数组:

static foo a[] = { foo(), foo(), foo() };

各个 foo 对象具有静态存储(即它们不在运行时分配)。

如果我有一个由两个或更多派生类继承的基类,则以下内容可以编译但由于切片而无法按预期工作:

static base a[] = { derived1(), derived2() };

这样的事情不应该导致切片发生:

static derived1 d1;
static derived2 d2;
static base *a[] = { &d1, &d2 };

我的问题是:如何在不声明 d1 的情况下做同样的事情?和 d2a分开,同时为单个(指向的)元素保留静态存储?以下给出了“获取临时地址”错误:

static base *a[] = { &derived1(), &derived2() };

也许可以定义一个 constexpr可变模板函数?像这样的东西:

template<typename... Args>
constexpr std::initializer_list<base *> base_array(Args... args) {
...
}

然后我可以写:

static base *a[] = base_ptr_array(derived1(), derived2());

也许这会有相同的“获取临时地址”问题,尽管我的想法是因为这是一个 constexpr,它的工作方式类似于 { foo(), foo(), foo() }以上(创建临时文件)。

最佳答案

您可以使用一些模板来避免声明那些静态变量:

#include <tuple>
#include <array>
#include <type_traits>
#include <utility>

template<class Base, class... Ts>
struct foo {
foo()
: foo(Ts{}..., std::index_sequence_for<Ts...>{})
{}
std::tuple<Ts...> deriveds;
std::array<Base*, sizeof...(Ts)> arr;

private:
template<std::size_t... Is>
foo(Ts... ts, std::index_sequence<Is...>)
: deriveds(ts...)
, arr{ &std::get<Is>(deriveds)...}
{}
};


// test
#include <iostream>

struct A {
virtual void show() const {
std::cout << "A\n";
}
virtual ~A() = default;
};
struct B: public A
{
void show() const override {
std::cout << "B\n";
}
};
struct C: public A
{
void show() const override {
std::cout << "C\n";
}
};

foo<A, A, B, C> f;

int main() {
for ( A *ptr : f.arr ) {
ptr->show();
}
}

关于c++ - 在 C++ 中,如何在不使用 new 且不单独声明单个元素的情况下创建 `std::initializer_list<base *>`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48851186/

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