gpt4 book ai didi

c++ - 编译时初始化和运行时访问包含派生元素的 initializer_list vector

转载 作者:行者123 更新时间:2023-11-30 02:31:30 24 4
gpt4 key购买 nike

在下面的代码中,初始化列表用 B 和 C 对象初始化,其 ctors 分别传入值“bbb”和 333。由于这些对象派生自 A,因此列表正确地创建了两个 A 元素。

#include <string>
#include <vector>
#include <iostream>

struct A
{
char ch;
};

struct B : A
{
B( std::string str ) : str( str ) {}
std::string str;
};

struct C : A
{
C( int num ) : num( num ) {}
int num;
};

struct D
{
D( std::initializer_list< A* > initializerList )
: variadicVect( initializerList )
{}

std::vector< A* > variadicVect;
};

int main()
{
D d { new B { "bbb" }, new C { 333 } };
d.variadicVect[ 0 ]->ch = 'm'; // ok, but accesses base member
//std::cout << d.variadicVect[ 0 ]->str << std::endl; // error C2039: 'str': is not a member of 'A'
//std::cout << d.variadicVect[ 1 ]->num << std::endl; // error C2039: 'num': is not a member of 'A'

return 0;
}

link 中报告了类似的问题由@Jarod42 解决。他确定对象切片是问题所在。为了避免这种按值赋值的问题,我新建了初始化列表对象,但仍然无法访问派生类。

我尝试的另一个尝试是模板化 initializer_list 类型(代码未显示),但我收到此错误:“D::variadicVect”:仅允许静态数据成员模板”

我的目标是能够使用在编译时选择派生类型的各种派生对象来初始化列表,并且能够在运行时正确访问它们。这可能吗?

最佳答案

要使您的代码编译通过,您必须将 vector 元素转换为适当的类型:

std::cout << static_cast<B*>(d.variadicVect[ 0 ])->str << std::endl;
std::cout << static_cast<C*>(d.variadicVect[ 1 ])->num << std::endl;

否则 C++ 将它们视为类型 A,并且只有来自 A 的接口(interface)可用。

其他解决方案是添加虚函数(virtual std::string Str(){return "";}virtual int Num(){return 0;} ) 到 A 并在需要时在基类中覆盖它们。那么你就不必施法了。示例如下:

http://coliru.stacked-crooked.com/a/ed7c73a5d8afa5e9

#include <string>
#include <vector>
#include <iostream>

struct A
{
char ch;
virtual std::string Str() { return ""; }
virtual int Num() { return 0; }
};

struct B : A
{
B( std::string str ) : str( str ) {}
std::string str;
std::string Str() override { return str; }
};

struct C : A
{
C( int num ) : num( num ) {}
int num;
int Num() override { return num; }
};

struct D
{
D( std::initializer_list< A* > initializerList )
: variadicVect( initializerList )
{}

std::vector< A* > variadicVect;

};

int main()
{
D d { new B { "bbb" }, new C { 333 } };
d.variadicVect[ 0 ]->ch = 'm'; // ok, but accesses base member
std::cout << d.variadicVect[ 0 ]->Str() << std::endl;
std::cout << d.variadicVect[ 1 ]->Num() << std::endl;

return 0;
}

关于c++ - 编译时初始化和运行时访问包含派生元素的 initializer_list vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37599782/

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