模板类型推导
Template type derivation
我需要使用模板实现 class,比如 'MyClass'。
template<class T>
class MyClass
{
public:
T var1;
T1 var2;
};
有两个成员变量var1和var2。如果 class 模板参数 'T' 是基本类型(例如:float、double 或 long double),变量 var1 和 var2 的类型应该与模板参数相同。即上例中的T1 = T。
但是如果模板参数是std::complex<T>
,我想要
T var1;
std::complex<T> var2;
如何在C++11中实现?
一个可能的解决方案是定义一个简单的类型特征来提取正确的类型
template <typename T>
struct myTypeTraits
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>>
{ using type = T; };
和MyClass
变成
template <typename T>
class MyClass
{
using T0 = typename myTypeTraits<T>::type;
T0 var1;
T var2;
};
如果你想确定T
是一个基本类型(或者你的意思是算术?),有点复杂。
一种可能的方法是定义一个类型特征来表示(true
或 false
)如果一个类型是 std::complex
template <typename>
struct isComplex : public std::false_type
{ };
template <typename T>
struct isComplex<std::complex<T>> : public std::true_type
{ };
下一步修改myTypeTraits
声明(无通用定义)和两个默认布尔值
template <typename T, bool = std::is_fundamental<T>::value,
bool = isComplex<T>::value>
struct myTypeTraits;
接下来的两个专业,第一个是基础知识,第二个是复杂类型
template <typename T>
struct myTypeTraits<T, true, false>
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>, false, true>
{ using type = T; };
MyClass
class 保持不变,但如果您尝试使用(通过示例)a std::string
.
实例化它,现在会出现错误
下面是一个完整的编译示例
#include <complex>
#include <type_traits>
template <typename>
struct isComplex : public std::false_type
{ };
template <typename T>
struct isComplex<std::complex<T>> : public std::true_type
{ };
template <typename T, bool = std::is_fundamental<T>::value,
bool = isComplex<T>::value>
struct myTypeTraits;
template <typename T>
struct myTypeTraits<T, true, false>
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>, false, true>
{ using type = T; };
template <typename T>
class MyClass
{
public: // public to check with the static_assert()
using T0 = typename myTypeTraits<T>::type;
private:
T0 var1;
T var2;
};
int main ()
{
MyClass<int> mi; // compile
MyClass<std::complex<float>> mc; // compile
// MyClass<std::string> ms; // compilation error
static_assert( std::is_same<int, decltype(mi)::T0>{}, "!" );
static_assert( std::is_same<float, decltype(mc)::T0>{}, "!" );
}
我需要使用模板实现 class,比如 'MyClass'。
template<class T>
class MyClass
{
public:
T var1;
T1 var2;
};
有两个成员变量var1和var2。如果 class 模板参数 'T' 是基本类型(例如:float、double 或 long double),变量 var1 和 var2 的类型应该与模板参数相同。即上例中的T1 = T。
但是如果模板参数是std::complex<T>
,我想要
T var1;
std::complex<T> var2;
如何在C++11中实现?
一个可能的解决方案是定义一个简单的类型特征来提取正确的类型
template <typename T>
struct myTypeTraits
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>>
{ using type = T; };
和MyClass
变成
template <typename T>
class MyClass
{
using T0 = typename myTypeTraits<T>::type;
T0 var1;
T var2;
};
如果你想确定T
是一个基本类型(或者你的意思是算术?),有点复杂。
一种可能的方法是定义一个类型特征来表示(true
或 false
)如果一个类型是 std::complex
template <typename>
struct isComplex : public std::false_type
{ };
template <typename T>
struct isComplex<std::complex<T>> : public std::true_type
{ };
下一步修改myTypeTraits
声明(无通用定义)和两个默认布尔值
template <typename T, bool = std::is_fundamental<T>::value,
bool = isComplex<T>::value>
struct myTypeTraits;
接下来的两个专业,第一个是基础知识,第二个是复杂类型
template <typename T>
struct myTypeTraits<T, true, false>
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>, false, true>
{ using type = T; };
MyClass
class 保持不变,但如果您尝试使用(通过示例)a std::string
.
下面是一个完整的编译示例
#include <complex>
#include <type_traits>
template <typename>
struct isComplex : public std::false_type
{ };
template <typename T>
struct isComplex<std::complex<T>> : public std::true_type
{ };
template <typename T, bool = std::is_fundamental<T>::value,
bool = isComplex<T>::value>
struct myTypeTraits;
template <typename T>
struct myTypeTraits<T, true, false>
{ using type = T; };
template <typename T>
struct myTypeTraits<std::complex<T>, false, true>
{ using type = T; };
template <typename T>
class MyClass
{
public: // public to check with the static_assert()
using T0 = typename myTypeTraits<T>::type;
private:
T0 var1;
T var2;
};
int main ()
{
MyClass<int> mi; // compile
MyClass<std::complex<float>> mc; // compile
// MyClass<std::string> ms; // compilation error
static_assert( std::is_same<int, decltype(mi)::T0>{}, "!" );
static_assert( std::is_same<float, decltype(mc)::T0>{}, "!" );
}