1

I'd need to modify a simple struct to accept multiple types of value parameters, as shown below:

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;
};

I tried to create a template from it, but with no luck. declaring one of these is like menuitems_t(nameString, val1, type); My only problem is that if I want to use a bool as the referenced value it won't accept it obviously. (I can cast it as a float, but that's not what I want.) What should I modify in it to accept any types?

John
  • 13
  • 2
  • First of all, unless it's a school or assignment requirement don't use pointers for arrays, use `std::vector` instead. Secondly, what you seem to be looking for is *templates*. Please take some time to read about them in your books. – Some programmer dude Feb 03 '20 at 13:54
  • Do you know the types that you want to be able to accepts? If so you could use std::variant – OutOfBound Feb 03 '20 at 13:54
  • Have you heard about our lord and savior, [Templates](https://en.cppreference.com/w/cpp/language/templates)? – NathanOliver Feb 03 '20 at 13:56
  • Or you could use a Generic type for the `value` field. What you can also do is looking at [this answer](https://stackoverflow.com/questions/874298/c-templates-that-accept-only-certain-types) and create your own template class that accepts every type except Float – Jimi Feb 03 '20 at 13:56
  • What should it do exactly? It is always safe to accept and ignore the parameter. Storing it for later use is problematic, since at the time of use you have no idea about the type that was there at the time of store. – n. m. could be an AI Feb 03 '20 at 14:00
  • How would you use the created object after? The way you implement `menuitems_t` will depend on its usage. – L. F. Feb 03 '20 at 14:17

1 Answers1

0

You could use a void*, but that's a very C-style and type-unsafe solution to the problem. Any other pointer can be converted to a void-pointer implicitly, but you need to keep track of the type yourself.

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

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

On a side note, you don't need a custom constructor and can just use aggregate-initialization. And it's better practice to use nullptr instead of 0.

Using templates would be more type-safe, but you need to keep track of types at compile-time.

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;
};

If there can only be a limited amount of types, you can use a std::variant. You could also just use a union, but unions don't have runtime type-safety like std::variant.

struct menuitems_t
{
    std::string name;
    std::variant<float, bool> value;
    int itemtype;
};
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
  • "Any other pointer can be converted to a void-pointer" - Nope. A pointer-to-member-function cannot be stored in a `void*`. – Jesper Juhl Feb 03 '20 at 16:00