druckermanly
druckermanly

Reputation: 2741

Varying the return type of a templated member function of a class based off of a separate templated member

Pardon the poor phraseology in my title, I think my example will do much more to show what I'm trying to do, and the problem I'm facing:

Here is a class template that I am currently trying to create:

template<typename T>
class IID{
public:
    IID(T x){a = x;}
    template<typename X>
    vector</*/////*/> operator()(X& rng, unsigned int n){
        vector</*/////*/> returnval(n);
        generate(returnval.begin(),returnval.end(),bind(a,ref(rng)));
        return returnval;   
    };
private:
    T a;
};

The constructor takes an input from the C++ random library. These classes are templated in the following manner:

uniform_int_distribution<double> T;

Is there a way to get the "double" from the above statement in the following line of code?

vector</*/////*/> operator()(X& rng, unsigned int n){

I can solve the problem by doing the following, but it contains a redundancy I'd like to avoid:

template<typename T, typename F>
class IID{
public:
    IID(T x){a = x;}
    template<typename X>
    vector<F> operator()(X& rng, unsigned int n){
        vector<F> returnval(n);
        generate(returnval.begin(),returnval.end(),bind(a,ref(rng)));
        return returnval;   
    };
private:
    T a;
};

Because it means that instantiation of a member of the IID class is of the form:

 uniform_real_distribution<double> dist(0,100);
 IID<uniform_real_distribution<double>, double > a(dist);

Which is littered with redundancies!

I'd much rather have:

 uniform_real_distribution<double> dist(0,100);
 IID<uniform_real_distribution<double> > a(dist);

which looks much cleaner.

Thank you for your time!

Upvotes: 0

Views: 39

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

Assuming there is no requirement on the random number generator you are using to define the type, the easiest way is to actually just get the value of the expression you are executing:

template<typename T>
class IID{
public:
    // ...
    template<typename X>
    auto operator()(X& rng, unsigned int n)
        -> std::vector<decltype(std::bind(std::declval<T&>(), std::ref(rng))())> {
        std::vector<decltype(std::bind(std::declval<T&>(), std::ref(rng))())> rc;
        std::generate_n(std::back_inserter(rc), n, std::bind(this->a, std::ref(rng)));
        return rc;
    }

private:
    T a;
};

Upvotes: 1

Related Questions