beginneR
beginneR

Reputation: 3291

Set template argument in other class in C++

Is there a way to set the template argument of a template class inside another class? I want to have a class that generates a distribution of a certain type (normal, uniform etc.) with two values. The class should be called like this:

Dist normal("normal",0,1) // this should construct std::normal_distribution<double> normal(0,1);
Dist uniform("uniform",1,10); //std::uniform_real_distribution<double> uniform(1,10);

One way would be to make the Dist class a template class as well. But I would like to Dist to be a non-template class. The reason is that I have another class that should get and std::vector of Dist as input (std::vector<Dist>). I cannot do this if Dist is a template class.

Upvotes: 0

Views: 98

Answers (1)

Vittorio Romeo
Vittorio Romeo

Reputation: 93264

But I would like to know if it is possible to do it the way shown above.

Yes, but I don't see why you would want to do that. You would need to use some sort of run-time "string to factory" map and type-erasure.

struct VectorBase
{
    virtual ~Vector() { }

    // Common interface
    virtual void something() { }
};

template <typename T>
struct VectorImpl : Vector
{
    std::vector<T> _v;

    // Implement common interface
    void something() override { }
};

struct Vector
{
    std::unique_ptr<VectorBase> _v;

    Vector(const std::string& type)
    {
        if(type == "int") 
            _v = std::make_unique<VectorImpl<int>>();
        else if(type == "double") 
            _v = std::make_unique<VectorImpl<double>>();
        else
            // error
    }

    // Expose common interface...
};

The recommended/optimal way is, as you mentioned, to make Vector a class template:

template <typename T>
struct Vector
{
    std::vector<T> _v;

    template <typename... Ts>
    Vector(Ts&&... xs) : _v{std::forward<Ts>(xs)...} { }
};

Usage:

Vector<int> IntVec(1, 2);
Vector<double> DoubleVec(1.0, 2.0);

Upvotes: 1

Related Questions