具有条件类型名称的模板 class
Template class with conditional typenames
我想要一个模板 class(例如 float
/double
类型),但我使用的是 Nvidia CUDA 和OptiX 并具有多种其他类型(例如 float2
、double2
、float3
、...),具体取决于所选模板类型。
像这样:
#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;
};
};
我现在的解决方案是有多个模板参数MyClass<T,T2,T3> my_object;
,但这似乎有太多的开销和混乱。有没有一种方法可以使用上述所需的单个模板参数实现相同的效果?
使用模板特化实现元函数,将标准 C++ 类型映射到具有所需“等级”的 OptiX 类型:
template <typename T, std::size_t N> struct optix_type;
template <> struct optix_type<float, 2> { using type = optix::float2; };
template <> struct optix_type<float, 3> { using type = optix::float3; };
template <> struct optix_type<double, 2> { using type = optix::double2; };
// ...
template <typename T, std::size_t N>
using optix_type_t = typename optix_type<T, N>::type;
然后您可以在 class(es) 中使用它来轻松获得正确的类型:
template <class T>
class MyClass {
using T2 = optix_type_t<T, 2>;
MyClass() {
T2 my_T2_variable;
optix_type_t<T, 3> my_T3_variable;
}
void SomeFunction() { T2 another_T2_variable; };
};
通常,您会通过创建特征类型来完成此操作,该特征类型的特化定义了其他类型。例如:
// 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
};
然后,如果需要,您可以将这些类型作为您的类型的别名:
template <typename T>
class MyClass {
public:
using T2 = typename optix_traits<T>::dim2;
};
您可以使用 std::conditional
,来自 <type_traits>
。
如果您希望 T2
在 T == float
时为 optix::float2
,否则为 optix::double2
,请使用 std::conditional
。自 c++11 起可用,并将在编译时解析类型 T2
。
#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)
正如 @HikmatFarhat 指出的那样,std::conditional
不会发现用户的错误。
它只检查第一个条件,对于 false
情况给出类型 optix::double2
.
另一个选项是 SFINAE ed 函数系列,decltype
到 T2
的函数如下:
#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)
我想要一个模板 class(例如 float
/double
类型),但我使用的是 Nvidia CUDA 和OptiX 并具有多种其他类型(例如 float2
、double2
、float3
、...),具体取决于所选模板类型。
像这样:
#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;
};
};
我现在的解决方案是有多个模板参数MyClass<T,T2,T3> my_object;
,但这似乎有太多的开销和混乱。有没有一种方法可以使用上述所需的单个模板参数实现相同的效果?
使用模板特化实现元函数,将标准 C++ 类型映射到具有所需“等级”的 OptiX 类型:
template <typename T, std::size_t N> struct optix_type;
template <> struct optix_type<float, 2> { using type = optix::float2; };
template <> struct optix_type<float, 3> { using type = optix::float3; };
template <> struct optix_type<double, 2> { using type = optix::double2; };
// ...
template <typename T, std::size_t N>
using optix_type_t = typename optix_type<T, N>::type;
然后您可以在 class(es) 中使用它来轻松获得正确的类型:
template <class T>
class MyClass {
using T2 = optix_type_t<T, 2>;
MyClass() {
T2 my_T2_variable;
optix_type_t<T, 3> my_T3_variable;
}
void SomeFunction() { T2 another_T2_variable; };
};
通常,您会通过创建特征类型来完成此操作,该特征类型的特化定义了其他类型。例如:
// 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
};
然后,如果需要,您可以将这些类型作为您的类型的别名:
template <typename T>
class MyClass {
public:
using T2 = typename optix_traits<T>::dim2;
};
您可以使用 std::conditional
,来自 <type_traits>
。
如果您希望 T2
在 T == float
时为 optix::float2
,否则为 optix::double2
,请使用 std::conditional
。自 c++11 起可用,并将在编译时解析类型 T2
。
#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)
正如 @HikmatFarhat 指出的那样,std::conditional
不会发现用户的错误。
它只检查第一个条件,对于 false
情况给出类型 optix::double2
.
另一个选项是 SFINAE ed 函数系列,decltype
到 T2
的函数如下:
#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)