【问题标题】:Make struct accept any type insted of float使结构接受任何类型而不是浮点数
【发布时间】:2020-02-03 13:51:53
【问题描述】:

我需要修改一个简单的结构来接受多种类型的值参数,如下所示:

struct menuitems_t
{
    menuitems_t(std::string name, float* value = 0, int itemtype = menuitemtype::SWITCH)
    {
        this->name = name;
        this->value = value;
        this->itemtype = itemtype;
    }

    std::string name;
    float* value;
    int itemtype;
};

我试图从中创建一个模板,但没有成功。 声明其中之一就像menuitems_t(nameString, val1, type); 我唯一的问题是,如果我想使用 bool 作为引用值,它显然不会接受它。 (我可以将它转换为浮点数,但这不是我想要的。) 我应该在其中修改什么以接受任何类型?

【问题讨论】:

  • 首先,除非是学校或作业要求,否则不要对数组使用指针,而是使用std::vector。其次,您似乎正在寻找的是模板。请花一些时间在您的书中阅读它们。
  • 您知道您希望能够接受的类型吗?如果是这样,您可以使用 std::variant
  • 你听说过我们的救世主Templates吗?
  • 或者您可以为value 字段使用通用类型。您还可以查看this answer 并创建自己的模板类,该类接受除 Float 之外的所有类型
  • 它到底应该做什么?接受和忽略参数总是安全的。存储以备后用是有问题的,因为在使用时您不知道存储时的类型。

标签: c++ templates struct declaration


【解决方案1】:

您可以使用void*,但这是一个非常 C 风格和类型不安全的问题解决方案。 任何其他指针都可以隐式转换为void-指针,但您需要自己跟踪类型。

struct menuitems_t
{
    std::string name;
    void* value;
    int itemtype;
};

void foo() {
    menuitems_t myItems{"name", nullptr, 0};
    // ...
}

附带说明,您不需要自定义构造函数,只需使用aggregate-initialization。 最好使用nullptr 而不是0

使用模板会更安全,但您需要在编译时跟踪类型。

template <typename T>
struct menuitems_t
{
    std::string name;
    T value; // or T* value if it's still supposed to be a pointer
    int itemtype;
};

如果类型数量有限,您可以使用std::variant。你也可以只使用union,但联合没有像std::variant 这样的运行时类型安全。

struct menuitems_t
{
    std::string name;
    std::variant<float, bool> value;
    int itemtype;
};

【讨论】:

  • “任何其他指针都可以转换为空指针” - 不。指向成员函数的指针不能存储在 void* 中。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多