[英]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;
};
};
我現在的解決方案是擁有多個模板 arguments MyClass<T,T2,T3> my_object;
,但這似乎有太多的開銷和混亂。 有沒有一種方法可以使用上面所需的單個模板參數來實現相同的目標?
通常,您會通過創建其特化定義附加類型的特征類型來做到這一點。 例如:
// 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
};
(見演示)
正如@HikmatFarhat指出的那樣, std::conditional
不會捕獲用戶錯誤。 它只檢查第一個條件,對於false
情況給出類型optix::double2
。
另一個選項是一系列 SFINAE ed 函數,以及對T2
的decltype
如下:
#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
};
(見演示)
使用將標准 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;
然后,您可以在您的課程中使用它來輕松獲得正確的類型:
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; };
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.