Consider the following implementation of a template class:
template<class T>
class MyClass
{
public:
void setVar1(const T& v1)
{
var1 = v1;
}
void setVar2(const T1& v2)
{
var2 = v2;
}
T var1;
T1 var2;
};
If the template parameter T
is a fundamental type (like float
, double
, or long double
) I would like to have T1 = T
.
If the template parameter T
is std::complex<float>
, I would like to have T=std::complex<float>
and T1 = float
. Similarly for std::complex<double>
and std::complex<long double>
.
Deducing the type of the variable is discussed at Template type derivation
However, the additional member functions prevents usage of their solution in this context.
A custom traits class would suffice. You can leverage partial specializations to select the type you want/need. Example code
template<typename T, bool F> class Base;
template<typename T>
class Base <T, true> {
public:
T var2;
};
template<typename T>
class Base <std::complex<T>, false> {
public:
typename std::complex<T>::value_type var2;
};
template <typename T>
class BaseHelper : public Base<T, std::is_fundamental<T>::value> {};
template<class T>
class MyClass : public BaseHelper<T> {
public:
using T1 = decltype(BaseHelper<T>::var2);
void setVar1(const T& v1) {
var1 = v1;
}
void setVar2(const T1& v2) {
this->var2 = v2;
}
T var1;
};
Live Example
There are many other ways though.
Based on Bo Personns comment and the answer provided at https://stackoverflow.com/questions/47334675/template-type-derivation
I got the following working example.
The content of my .h file is as follows.
#include <iostream>
#include <complex>
#include <typeinfo>
template <typename T>
class MyClass
{
template <typename T0>
struct myTypeTraits
{ using type = T0; };
template <typename T0>
struct myTypeTraits<std::complex<T0>>
{ using type = T0; };
public:
using T0 = typename myTypeTraits<T>::type;
void setVar1(const T0& v);
void setVar2(const T& v);
T getVar2() const;
void print() const;
T0 var1;
T var2;
};
The .cpp file contains the following lines of code.
template <class T>
void MyClass<T>::setVar1(const T0& v)
{
var1 = v;
}
template <class T>
void MyClass<T>::setVar2(const T& v)
{
var2 = v;
}
template <class T>
T MyClass<T>::getVar2() const
{
return var2;
}
template <typename T>
void MyClass<T>::print() const
{
std::cout<<"var1: "<<var1<<std::endl;
std::cout<<"var2: "<<var2<<std::endl;
}
int main()
{
MyClass<float> tmp;
MyClass<std::complex<float> > tmp1;
tmp.print();
tmp1.print();
return 0;
}
The above code works as intended.
However, I have another related question posted at Template type deduction in function return type