2011-11-12 134 views
4

我已经创建了一个类型列表。然后我使用传递类型列表的模板创建一个类。当我用某些未指定的类型调用该类的打印函数时,它们会被铸造。我怎样才能在编译时强制确切的类型?所以如果我使用一个不公开的类型,我会得到一个编译器错误。 谢谢。编译时间类型检查C++

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

你的'print'函数并不是很有用,因为它没有实现任何递归。 –

回答

4

添加一个私有函数模板

template<typename T> void print(T); 

,并不需要实现。这应该捕获所有没有明确打印的类型,并且由于它是私有的,它会给出错误消息。

+0

感谢您解决了我的问题。指出时似乎很明显:) – Stigodump

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_samedecay<type_traits>,但如果你没有C + +11,你可以从TR1或Boost中取出它们,或者自己写下它们,因为它们是非常简单的类型修饰符类。

条件最好进入static_assert,这是另一个C++ 11功能,但是存在类似的C++ 98/03结构,在某种情况下会产生编译时错误。

+0

+1你可以看到你已经在踩踏那个话题:) – sehe

+0

@sehe:它已经跨过我的路径,确实如此:-) –

+0

感谢这帮助了我的下一个问题,使它创建不同大小类型的打印功能名单。 – Stigodump

0

你可以通过非const引用来强制它们是完全相同的类型。但是,你不能再使用const变量或文字。

+0

谢谢我现在开始从另一个角度看待这些问题。 – Stigodump