强制非特定模板实例化的编译错误

时间:2012-12-12 23:27:44

标签: c++ templates template-specialization

好的,这是我第一次涉足模板,这可能是几个非常愚蠢,简单的问题中的第一个。

考虑:

template <class T>
void sendit(char *buffer, unsigned len)
{
   // force compile error
}

void sendit<first_valid>(char *buffer, unsigned len)
{
   // this is OK
}


void sendit<second_valid>(char *buffer, unsigned len)
{
   // this is OK
}

基本上,我的想法是我有一套可以通过sendit()程序合法操作的“东西”,我会专门为这些东西设计模板。如果用户试图调用sendit(),(好的,技术上,sendit()),我想在他面前抛出一个编译错误。

这可行吗?如果是这样,怎么样?

这是一种合理的方法吗?

1 个答案:

答案 0 :(得分:3)

保持未定义:

template <class T>
void sendit(char *buffer, unsigned len);

// C++11
template <class T>
void sendit(char *buffer, unsigned len) = delete;

使用= delete是首选方法IMO。

或者,做一些静态断言(在C ++ 03中使用Boost):

template <class T>
void sendit(char *buffer, unsigned len) {
    static_assert(sizeof(T) == 0, "must specialize"); // must use sizeof to make it dependant on T
}

无论如何,你确定你真的需要类型模板吗?我并不是说你不应该这样做,只是要知道有些替代方案涉及重载,例如:

// This is only if you're using the types as tags
// Don't do this otherwise!!!

void sendit(first_valid, char *buffer, unsigned len)
{
   // this is OK
}


void sendit(second_valid, char *buffer, unsigned len)
{
   // this is OK
}

sendit(first_valid(), ...); // call first
sendit(second_valid(), ...); // call second

或使用枚举而不是类型作为模板参数:

enum foo { first, second }

template <foo Foo>
void sendit(char *buffer, unsigned len);

void sendit<first>(char *buffer, unsigned len)
{
   // this is OK
}