I would like to have a template class (e.g. float
/double
type), but I am using Nvidia CUDA and OptiX and have multiple other types (e.g. float2
, double2
, float3
,...) that depend on the chosen template type.
Something like this:
#include <optixu/optixu_vector_types.h>
#include <type_traits>
template <class T>
class MyClass
{
MyClass()
{
if (std::is_same<T, float>::value)
{
typedef optix::float2 T2;
}
else if (std::is_same<T, double>::value)
{
typedef optix::double2 T2;
}
T2 my_T2_variable;
}
void SomeFunction()
{
T2 another_T2_variable;
};
};
My solution for now is to have multiple template arguments MyClass<T,T2,T3> my_object;
, but this seems to have too much overhead and clutter. Is there a way to achieve the same with a single template argument as desired above?
Typically you'd do this by creating a trait type whose specializations define the additional types. For example:
// Base template is undefined.
template <typename T>
struct optix_traits;
template <>
struct optix_traits<float> {
using dim2 = optix::float2;
// etc
};
template <>
struct optix_traits<double> {
using dim2 = optix::double2;
// etc
};
Then you can alias from these types to a name in your type, if desired:
template <typename T>
class MyClass {
public:
using T2 = typename optix_traits<T>::dim2;
};
You can use std::conditional
, from <type_traits>
.
If you want the T2
be optix::float2
when T == float
and otherwise optix::double2
, use std::conditional
. This is availble since c++11 and will resolve the type T2
at compile time.
#include <type_traits> // std::conditional, std::is_same
template <class T>
class MyClass
{
using T2 = typename std::conditional<std::is_same<T, float>::value,
optix::float2, optix::double2>::type;
T2 my_T2_variable;
// ... other code
};
(See demo)
As @HikmatFarhat pointed out, std::conditional
will not catch the user mistakes.
It checks only the first condition, and for the false
case gives the type optix::double2
.
Another option is series of SFINAE ed functions, and decltype
to those for the T2
as follows:
#include <type_traits> // std::is_same, std::enable_if
template <class T> // uses if T == float and return `optix::float2`
auto typeReturn() -> typename std::enable_if<std::is_same<float, T>::value, optix::float2>::type { return {}; }
template <class T> // uses if T == double and return `optix::double2`
auto typeReturn() -> typename std::enable_if<std::is_same<double, T>::value, optix::double2>::type { return {}; }
template <class T>
class MyClass
{
using T2 = decltype(typeReturn<T>()); // chooses the right function!
T2 my_T2_variable;
// ... other codes
};
(See demo)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With