我试图做一个仅在某些情况下运行函数的模板化类。这是我的代码:
#include "stdafx.h"
#include <string>
#include <iostream>
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
class NullType
{
};
typedef Typelist<int, Typelist<float, Typelist<char*, NullType> > > UsableTypes1;
typedef Typelist<short, Typelist<std::string, NullType> > UsableTypes2;
template <class T>
class MyClass
{
public:
MyClass();
private:
Typelist _types;
};
template<class T>
MyClass<T>::MyClass()
{
_types = T;
}
template<class T>
void MyClass<T>::print(T type)
{
}
MyClass<UsableTypes1> any;
我不仅需要传递给print()函数的变量是一种可用类型的类型,还需要使代码编译。我知道,如果使用不正确的类型调用print,可能必须使用std :: enable_if来允许代码编译或不使用,而使用std :: is_same来检查类型,但是我不知道如何组合该函数带有模板化的类。
这是一个测试类,可以帮助解释我要实现的目标:
MyClass<UsableTypes1> one;
void TestMyClass()
{
int int_val = 0;
float flt_val = 0.1f;
const char* char_val = "Hi";
short short_val = 10;
std::string str_val = "Hello";
one.print(int_val); // OK
one.print(flt_val); // OK
one.print(char_val); // OK
// one.print( short_val); // compile error
// one.print( str_val ); // compile error
}
特别是我不知道如何向print()添加一个非T型参数。
希望您能帮助我! 预先谢谢你。
答案 0 :(得分:1)
我不知道您是否有充分的理由使用递归Typelist
来包含类型列表。更直接的方法是使Typelist
为可变参数模板。
然后,我们可以添加一个constexpr
函数,如果给定类型是Typelist
的一部分,则该函数返回true。
std::disjunction
需要c++17
,但是可以使用递归模板为c++11
编写等效的内容。但是那会更加冗长。
#include <iostream>
#include <type_traits>
struct NullType {};
template <typename T, typename U>
struct Typelist {
using Head = T;
using Tail = U;
template <typename Type>
static constexpr bool IsUsable() {
return std::is_same<Type, T>::value;
}
};
template <typename T, typename... U>
struct Typelist<T, Typelist<U...>> {
using Head = T;
using Tail = Typelist<U...>;
template <typename Type>
static constexpr bool IsUsable() {
return std::is_same<Type, T>::value || Typelist<U...>::template IsUsable<Type>();
}
};
using UsableTypes1 = Typelist<int, Typelist<float, Typelist<const char*, NullType>>>;
template <class T>
class MyClass
{
public:
template <typename U>
void print(U u) {
static_assert(T::template IsUsable<U>(), "That is not a usable type");
std::cout << u << std::endl;
}
};
MyClass<UsableTypes1> one;
int main()
{
int int_val = 0;
float flt_val = 0.1f;
const char* char_val = "Hi";
short short_val = 10;
std::string str_val = "Hello";
one.print(int_val); // OK
one.print(flt_val); // OK
one.print(char_val); // OK
// one.print( short_val); // compile error
// one.print( str_val ); // compile error
}