exocortex
exocortex

Reputation: 503

Derive a templated class' member variable type from a template member type

The title might seem a little confusing, so here is a more thorough explanation:

I have a templated class that has a vector as a member variable. The template argument is a struct (or class) that will have one certain variable. The type of this vector shall be derived from the template argument (from this one certain variable). The tricky part is that it shall be derived from a member variable of the template argument.

#include <vector>
#include <complex>
using namespace std;

struct thingA {
    double variable;
    //...
};

struct thingB {
    complex<double> variable;
    //...
};


template <class S>
class someClass {
    vector< " type of S::variable " > history; // If S=thingA, make it a double, if S=tingB make it a complex<double>
}

// Usage:
someClass<thingA> myInstanceA; // (this instance should now have a vector<double>)

someClass<thingB> myInstanceB; // (this instance should now have a vector<complex<double>>)

Upvotes: 14

Views: 1352

Answers (2)

mch
mch

Reputation: 9804

I would define the type in the structs and use it in the class:

#include <vector>
#include <complex>
using namespace std;

struct thingA {
    using Type = double;
    Type variable;
    //...
};

struct thingB {
    using Type = complex<double>;
    Type varbiable;
    //...
};


template <class S>
class someClass {
    vector<typename S::Type> history; // if S=thingA, make it a double, if S=tingB make it a complex<double>
};

// usage:
someClass<thingA> myInstanceA; // (this instance should now have a vector<double>)

someClass<thingB> myInstanceB; // (this instance should now have a vector<complex<double>>)

https://godbolt.org/z/raE9hbnqW

That is also the way to go when the variables do not have the same name.

Upvotes: 14

songyuanyao
songyuanyao

Reputation: 172934

You can get the type via decltype, if the names of data member are always the same:

template <class S>
class someClass {
    vector< decltype(S::variable) > history; // if S=thingA, make it a double, if S=tingB make it a complex<double>
};

Upvotes: 17

Related Questions