禁用模板但允许特化

时间:2016-11-24 10:19:14

标签: c++ templates

例如,我已经声明了一个通用模板:

template <class T>
void foo(T value);

但是我需要每个类型的程序员必须声明它的特化:

struct my_user_t
{
// ...
};

template <>
void foo<my_user_t>(my_user_t value) {
  // ...
}

// Somewhere in big program:
my_user_t my_value;
foo(my_value);

目前,如果程序员忘记为他的用户类型专门化模板,链接器会说它找不到符号,而不是编译器。所以在大型程序中很难找到它的使用位置。

如何声明模板:

template <class T>
void foo(T value) {
    static_assert(???, "You must specialize foo<> for your type");
}

这样编译器(而不是链接器)会错误地说出foo(my_user_t)的使用位置?

3 个答案:

答案 0 :(得分:4)

只需构建依赖于模板参数类型的内容:

template<typename T>
struct always_false : std::false_type {};

template <class T>
void foo(T value) {
    static_assert(always_false<T>::value , "You must specialize foo<> for your type");
}

或者,我认为您可以将默认功能模板声明为已删除:

template <class T>
void foo(T value)=delete;

答案 1 :(得分:0)

以下是使用sizeof提供的产品:

template<class T> void foo(T) {
    static_assert(sizeof(T) != sizeof(T), "You must specialize foo<> for your type");
}

答案 2 :(得分:0)

您可以使用函数重载而不是模板。 因此编译器必须至少看到它的声明,而程序员很可能不会忘记在为自己的类型添加声明后添加函数定义。

另一种方法是使用具有空类定义的类模板(该函数将成为成员函数)。