0

I have a Dynamic class that can store different types : int, double, std::vector<int>, std::vector<double>, etc. I have about 50 of such types.

I would like my Dynamic type to have a constructor where we give two informations:

  • The type to be stored
  • Arguments used to construct the type inside the Dynamic class

I am looking forward to something such as

const Dynamic x<std::vector<double>>{10};

to construct in place a Dynamic object that has a std::vector<double> of length 10.

PS: I am allowed to use C++11 and I am not allowed to use RTTI

jotik
  • 17,044
  • 13
  • 58
  • 123
InsideLoop
  • 6,063
  • 2
  • 28
  • 55
  • 3
    You can't have explicit template arguments with constructors. And why can't you use RTTI yet have to do something like this? – Passer By Jan 23 '18 at 15:49
  • It's not clear to me exactly what you are trying to achieve, but [this question](https://stackoverflow.com/questions/3960849/c-template-constructor) on templated constructors may be relevant. Essentially, you cannot provide template arguments for a constructor, they must all be deduced. – François Andrieux Jan 23 '18 at 15:49
  • @Passer By: I am designing a library and some of my clients compile without RTTI. And I need such a `Dynamic` object to load JSON files for instance. – InsideLoop Jan 23 '18 at 15:51
  • @François: Thanks. I guess I need to forget about this constructor. Too bad. – InsideLoop Jan 23 '18 at 15:52
  • Look here: https://stackoverflow.com/questions/20775285/how-to-properly-use-tag-dispatching-to-pick-a-constructor – PiotrNycz Jan 23 '18 at 15:53

2 Answers2

4

Constructor template arguments must be deduced. They cannot be provided explicitly. You can get around this by providing a type tag which encodes the wanted template argument and passing it as an additional constructor argument. For example :

#include <utility>  // For std::forward

struct foo
{
    // Helper tag type
    template<class T>
    struct type_tag {};

    // The template argument T is deduced from type_tag<T>
    template<class T, class ... Args>
    foo(type_tag<T>, Args&&... p_args)
    {
        T value{ std::forward<Args>(p_args)... };
    }
};

int main()
{
    // Provide a type tag so the template argument can be deduced
    foo bar{ foo::type_tag<int>{}, 5 };
}
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
0

As long as you don't mind putting the type info next to Dynamic rather than the variable name you can do this with variadic args:

#include <iostream>
#include <vector>

template <typename T>
class Dynamic
{
public:
    template <typename... Args>
    Dynamic(Args... args) : data_(args...)
    {
    }

    T data_;
};

int main()
{
    const Dynamic<std::vector<double>> x{10};

    std::cout << x.data_.size() << std::endl;
}
Mark B
  • 95,107
  • 10
  • 109
  • 188