编译时间类型检查C ++

时间:2011-11-12 18:25:55

标签: c++ templates casting

我创建了一个类型列表。然后我使用传递类型列表的模板创建一个类。当我使用未指定的某些类型调用类的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实例,还是创建一个实例,我必须为每种类型创建一个打印函数? 我觉得我几乎拥有了所有的障碍,但却无法将它们融合在一起。我们非常感谢您提供的任何帮助。感谢。

3 个答案:

答案 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变量或文字一起使用。