I have the following classes. I would like to have "class First" with a template, and depending on it's type, set the type for "class Second", like the following.
template<typename T>
class Second
{
public:
T Get(T t)
{
return t;
}
};
template<typename T>
class First
{
public:
// if T=double --> vector<double>, if T=string --> long
Second<"auto deduce"> second;
};
int main()
{
First<int> first; // compile error, not in list
auto val = first.second.Get(1);
}
I can get it to work like this, but would rather avoid the following:
#include <iostream>
#include <vector>
#include <string>
template<typename T>
class Second
{
public:
T Get(T t)
{
return t;
}
};
template<typename T, typename U>
class First
{
public:
Second<U> second;
};
int main()
{
First<double, std::vector<double>> a;
First<std::string, long> b;
}
Been trying to get something to work with constexpr. I believe I could use std::conditional_t, but it doesn't look clean since std:: conditional
will require nesting itself in the template call.
Mapping ("auto-deduce") can be done simply with template specialization:
#include <string>
#include <vector>
// --------------------------------
// "Auto deduce"
// --------------------------------
template<typename T>
struct deduce;
template<>
struct deduce<double>
{
using type = std::vector<double>;
};
template<>
struct deduce<std::string>
{
using type = long;
};
template<typename T>
using deduce_t = typename deduce<T>::type;
// --------------------------------
// Your code
// --------------------------------
template<typename T>
class Second
{
public:
T Get(T t)
{
return t;
}
};
template<typename T>
class First
{
public:
Second<deduce_t<T>> second;
};
int main()
{
// First<int> first; // This would fail to compile
First<double> first;
auto val = first.second.Get({1});
static_assert(std::is_same<decltype(val), std::vector<double>>::value, "");
}