从派生类对基类中的占位缓冲区进行别名化

Aliasing a placeholding buffer in base class from derived class

提问人:glades 提问时间:5/11/2022 最后编辑:Some programmer dudeglades 更新时间:5/11/2022 访问量:39

问:

我想创建一个结构对象数组,每个对象都包含一个包含值的成员。但是,此值的类型可能因对象而异。由于大小不能变化,我决定在基类中放置一个占位缓冲区,我尝试从模板化为类型的派生类中别名。但这行不通:

#include <iostream>
#include <string>

struct some_struct_base
{
    std::string name_;
    char placeholder_[sizeof(std::string)];
    some_struct_base* next_;
    some_struct_base* prev_;
};

template <typename T>
struct some_struct : some_struct_base
{
    using val = static_cast<T>(some_struct_base::placeholder_);
};


int main()
{
    std::cout << sizeof(some_struct<std::string>) << std::endl;

    some_struct_base arr[10]; // <-- this is why the size needs to be fixed
    std::cout << static_cast<some_struct<std::string>>(arr[10]).val << std::endl; // <-- allow this
}

收益 率:

<source>:99:17: error: expected type-specifier before 'static_cast'
   99 |     using val = static_cast<T>(some_struct_base::placeholder_);
      |                 ^~~~~~~~~~~

我可以半途而废地理解这一点,因为 val 定义了一个类型而不是变量名称。但是我不想向派生类引入新成员(例如引用成员),因为这需要在嵌入式系统上运行,而另外 4 个字节已经要求太多了。

我怎样才能用最小的空间/没有额外的开销来实现这一点?

C++ 模板 C++17 基类 内存别名

评论

0赞 Some programmer dude 5/11/2022
在构造函数中创建一个初始化的引用?val
0赞 glades 5/11/2022
@Someprogrammerdude 这会增加 4/8 字节。应该有另一种方法。
0赞 Some programmer dude 5/11/2022
那么我能想到的唯一解决方案是吸气函数。或者重新考虑设计,这样你就不需要别名了。
1赞 simre 5/11/2022
你为什么不直接创建一个函数作为?因此,您不需要任何棘手的额外变量。编译器可以很容易地内联它,从而在运行时产生 0 开销。但!您可能需要,因为您可能无法强制转换为请求的类型...T* val() { return static_cast<T*>(some_struct_base::placeholder_); }reinterpret_castchar*T
1赞 simre 5/11/2022
@glades 或者,您可能可以在函数中取消引用,以便获得引用而不是指针,但我不是 100% 它会起作用......但!你必须小心!由于您使用的是 char[] 缓冲区,因此您必须就地构造字符串,然后进行 destruct,因为它没有简单的默认构造函数或析构函数!!*(object.val()) = <something...>val()

答: 暂无答案