1

I want to have a class that holds a data member whose type can vary. Something like:

struct container
{
    void push( auto x );
private:
    auto m_x;
};

Where the type isn't known until I call push(). How would I do this?

template boy
  • 10,230
  • 8
  • 61
  • 97

3 Answers3

4
template<typename T>
struct container
{
    void push(T x);
private:
    T m_x;
};
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 1
    The type isn't known until I call `push()`. – template boy May 20 '14 at 00:54
  • 2
    The class HAS TO BE instantiated when you invoke its member function, so you basically have to know the type of `m_x` before invoking `push` – vsoftco May 20 '14 at 00:54
  • A member function can be templated. You don't have to template the entire class. However, if a class member depends on the type of the method, then yes, you have to template the entire class. – Remy Lebeau May 20 '14 at 00:56
  • @RemyLebeau Yes but the member variable is templated to receive the element in push. This must be defined at instantiation. – Fantastic Mr Fox May 20 '14 at 00:57
  • @RemyLebeau The member function indeed, but what about the private member? You cannot "change" its type at runtime. – vsoftco May 20 '14 at 00:57
  • I won't know the type at compile time. The type is determined through runtime means. – template boy May 20 '14 at 00:58
  • Then templates are not what you need. The whole point of templates is for compile-time type variance of a generic interface. – aruisdante May 20 '14 at 00:59
  • @templateboy There is no way, when you instantiate the class, the variable `m_x` has to have a definite type. – vsoftco May 20 '14 at 00:59
  • 1
    @templateboy You may find `boost::any` http://www.boost.org/doc/libs/1_55_0/doc/html/any.html or `boost::variant` http://www.boost.org/doc/libs/1_55_0/doc/html/variant.html helpful – vsoftco May 20 '14 at 01:01
1

You could try boost::any, which lets you store any type but the later retrieval and use must be aware of the actual type (it may try a specific type, work through a list of potential types...).

If you may need to store any type but later during retrieval only need to perform certain operations on the value (for example, streaming the value to a std::ostream, adding it to another such value, ...), you can capture those operations as pointers to function template instantiations, or by instantiating a class template in which the operations are overrides of base class methods, such that your container can store a pointer to the base class and dispatch using runtime polymorphism.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
1

In C++, it's not possible to implement a class that holds a data member whose type can vary.

Depending on your exact needs, the following solutions come close:

  • Implement a class template. Instantiate the class template to get the class you need.
  • Use a pointer or a reference as data member.

Both solutions fall short in one way or the other; it depends on the exact problem which one is better suited.

Oswald
  • 31,254
  • 3
  • 43
  • 68