c++ 模板化抽象基类数组,不违反严格别名规则
Posted
技术标签:
【中文标题】c++ 模板化抽象基类数组,不违反严格别名规则【英文标题】:c++ array of templated abstract-base-class without breaking strict-aliasing rule 【发布时间】:2018-11-30 18:07:16 【问题描述】:在不违反严格别名规则的情况下,创建从抽象模板基类派生的对象数组的最佳方法是什么?每个派生对象都会以不同的方式定义基类的模板参数,但只能通过常量枚举值。这是一个例子
enum BlaEnum
Bla1,
Bla2,
Bla3
;
template <class T, BlaEnum bla = Bla1>
class A
public:
virtual void Foo() = 0;
T att;
BlaEnum bll;
;
class B : public A<int, BlaEnum::Bla2>
public:
void Foo() override;
;
class C : public A<int, BlaEnum::Bla3>
public:
void Foo() override;
;
int main(void)
B b;
C c;
//violates strict-aliasing rule
A<int>* BaseArr[2] = (A<int>*)&b,(A<int>*)&c ;
【问题讨论】:
具有不同实际类型参数的实例是不同的类,彼此无关(通过继承或任何其他关系),尽管有共同的模板名称。 【参考方案1】:这里的问题是class B : public A<int, BlaEnum::Bla2>
和class C : public A<int, BlaEnum::Bla3>
派生自彼此不兼容的不同A
。这些类中的每一个都会导致一个新模板类的实例化(它们都不兼容A<int>
)。
为了拥有有效的公共基础,您需要一个与派生类在任何模板参数(或者是非模板类)上都没有区别的基类。 修改您的示例,例如:
template <class T>
class Base
public:
virtual void Foo() = 0;
;
template <class T, BlaEnum bla = Bla1>
class A : public Base<T>
public:
T att;
BlaEnum bll;
;
// B and C are unchanged
int main()
B b;
C c;
// Array of pointers to common base class
Base<int>* BaseArr[2] = &b,&c ;
另一个注意事项:C 风格的数组不是一个好习惯,您应该更喜欢 std::array
(或 std::vector
)和智能指针而不是原始指针
【讨论】:
以上是关于c++ 模板化抽象基类数组,不违反严格别名规则的主要内容,如果未能解决你的问题,请参考以下文章
如何投射 sockaddr_storage 并避免违反严格的别名规则