我创建了一个类型列表。然后我使用传递类型列表的模板创建一个类。当我使用未指定的某些类型调用类的print函数时,它们会被转换。如何在编译时强制执行确切的类型?因此,如果我使用未列出的类型,我会收到编译器错误。 谢谢。
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
class NullType
{
};
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
template<class T>
class MyClass
{
public:
void print(T::Head _Value) { std::cout << _Value; }
void print(T::Tail::Head _Value) { std::cout << _Value; }
void print(T::Tail::Tail::Head _Value) { std::cout << _Value; }
private:
};
MyClass<UsableTypes> testclass;
void TestMyClass()
{
int int_val = 100000;
float flt_val = 0.1f;
char* char_val = "Hi";
short short_val = 10;
std::string str_val = "Hello";
testclass.print( int_val ); // OK 8-)
std::cout << endl;
testclass.print( flt_val ); // OK 8-)
std::cout << endl;
testclass.print( char_val ); // OK 8-)
std::cout << endl;
testclass.print( short_val); // this compiles OK and works ??? 8-(
std::cout << endl;
testclass.print( str_val ); // compile error 8-)
std::cout << endl;
}
@Kerrek SB:您好我认为它将帮助我完成下一步,即根据t_list内容,类型和类型数量创建打印功能。但我正在努力分离编译时处理和运行时处理。我要做的是为列表中的每种类型创建一个打印功能。因此,如果列表有两种类型,将创建两个打印功能,如果有五种类型,则将为每种类型创建一个打印功能。 当我这样做时:
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
MyClass<UsableTypes> newclass
这会为列表中的每个类型创建一个MyClass实例,还是创建一个实例,我必须为每种类型创建一个打印函数? 我觉得我几乎拥有了所有的障碍,但却无法将它们融合在一起。我们非常感谢您提供的任何帮助。感谢。
答案 0 :(得分:4)
添加私人功能模板
template<typename T> void print(T);
不需要实现。这应该捕获所有没有显式打印的类型,并且由于它是私有的,它将给出错误消息。
答案 1 :(得分:2)
您必须将print
函数放入模板中,然后检查类型是否匹配:
template <typename U>
void print(const U & u)
{
// use std::is_same<typename std::decay<T::Head>::type, typename std::decay<U>::type>::value
}
此处我正在从is_same
窃取decay
和<type_traits>
,但如果您没有C ++ 11,则可以从TR1或Boost中获取它们,或者只是自己编写,因为它们是非常简单的类型修饰符类。
条件最好进入static_assert
,这是另一个C ++ 11特性,但是在C ++ 98/03中存在类似的结构,在一定条件下会产生编译时错误。 / p>
答案 2 :(得分:0)
你可以通过非const引用来获取你的参数,强制它们是完全相同的类型。但是,您不能再将其与const变量或文字一起使用。