在C++中,如何在没有新元素且不单独声明单个元素的情况下创建"std::initializer_list<base *>"?
In C++, how can I create a `std::initializer_list<base *>` without new and without declaring individual elements separately?
在C 中,您可以在文件范围上声明某些内容:
static foo a[] = { foo(), foo(), foo() };
单个foo对象具有静态存储(即,在运行时未分配它们(。
如果我有两个或多个派生类继承的基类,则以下将编译但由于切片而无法正常工作:
static base a[] = { derived1(), derived2() };
这样的事情不应导致切片发生:
static derived1 d1;
static derived2 d2;
static base *a[] = { &d1, &d2 };
我的问题是:如何在不必与a
分开声明d1
和d2
的情况下执行相同的操作,而在为个人(尖头(元素保留静态存储时?以下给出了"临时地址"错误:
static base *a[] = { &derived1(), &derived2() };
也许可以定义 constexpr
variadic模板函数?类似:
template<typename... Args>
constexpr std::initializer_list<base *> base_array(Args... args) {
...
}
然后我可以写:
static base *a[] = base_ptr_array(derived1(), derived2());
也许这会有相同的"暂时地址"问题,尽管我的想法是,由于这是一个constexpr,它的工作方式与上面的{ foo(), foo(), foo() }
相似( create extence exture exture exturearies(。
您可以使用一些模板避免声明这些静态变量:
#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 << "An";
}
virtual ~A() = default;
};
struct B: public A
{
void show() const override {
std::cout << "Bn";
}
};
struct C: public A
{
void show() const override {
std::cout << "Cn";
}
};
foo<A, A, B, C> f;
int main() {
for ( A *ptr : f.arr ) {
ptr->show();
}
}
说实话,我认为您正在尝试将错误的工具用于工作。这是我看到的:
- 您想要来自数组元素的多态性行为。
- 您有一组有限的课程。如果打开的话,您将无法为数组编写初始化器。
这对我来说是"封闭的"多态性。您可以在C 17中无动态分配而实现它。您甚至不需要课程就可以拥有一个普通的基础课。只有您希望打电话给相同的成员。它所需要的是类型的std::variant
和一系列变体:
using variant_type = std::variant<derived1, derived2, ..., derived_n>;
static variant_type a[] = {
derived1(), derived2(), ..., derived_n()
};
,你有它。您获得了多态性行为,只需要std::visit
一个数组元素,而不是通过指针调用成员函数:
for(auto& v : a)
std::visit([](auto& e) {
// Do something with e
// It's a reference to one of the types the variant can hold
}, v);
相关文章:
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 如何在不迭代的情况下对数组中的每个元素调用方法
- 是否可以在不复制的情况下访问undered_map中的元素
- 在给定元素在螺旋上的位置的情况下,在二维数组中查找元素
- 我怎样才能在不重复的情况下随机迭代向量的每个元素
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- 在这种情况下,如何返回对数组中元素的引用?
- 是否可以在不显式迭代每个元素的情况下深度复制指针容器?
- 如何在不使用标准算法的情况下在排序向量中添加 c 元素?
- 在不调用构造函数的情况下创建 Vector 元素
- 在C++中,如何在没有新元素且不单独声明单个元素的情况下创建"std::initializer_list<base *>"?
- 如何在使用和无发现的情况下使用和不使用的字符串向量搜索元素
- 如何在不使用循环或迭代器的情况下检查所有列表元素并在满足条件时删除一个
- 如何在不使用 C++ 函数的情况下显示链表中的元素
- 如何在给定迭代器列表的情况下从向量中删除元素
- 我如何在C 中制作算法,以在不重复的情况下查找集合的变化(即n元素,选择k)
- 如何在不知道大小的情况下编写过程来修改动态数组的元素和大小
- 如何在不修改现有函数的情况下反转数组中除第一个和最后一个元素之外的所有元素