如何强制使用模板专业化?

时间:2012-01-13 16:58:13

标签: c++ template-specialization

如果实例化非专用基本版本,我正在尝试使模板函数产生编译时错误。我尝试了通常的编译时断言模式(负数组大小),但即使没有实例化模板,编译也会失败。当且仅当基础模板函数被实例化时,有关如何使其失败的任何想法?

template<class Foo> void func(Foo x) {
  // I want the compiler to complain only if this function is instantiated.
  // Instead, the compiler is complaining here at the declaration.
  int Must_Use_Specialization[-1];
}

template<> void func(int x) {
  printf("Hi\n");
}

5 个答案:

答案 0 :(得分:18)

不定义它是最简单的解决方案:

template<class Foo> void func(Foo x);

template<> void func(int x) {
  printf("Hi\n");
}

您也可以在CPP文件和use this中定义它们。

静态断言方法:

template<class Foo> void func(Foo x) {
  static_assert(sizeof(Foo) != sizeof(Foo), "func must be specialized for this type!");
}

答案 1 :(得分:7)

在C ++ 11中,您可以像这样使用static_assert

template<typename T> struct fake_dependency: public std::false_type {};
template<class Foo> void func(Foo x) {
   static_assert(fake_dependency<Foo>::value, "must use specialization");
}

fake_dependency结构是使断言依赖于模板参数所必需的,因此它等待评估,直到模板被实例化。您可以像这样修复您的解决方案:

template<class> struct fake_dependency { enum {value = -1 }; };

template<class Foo> void func(Foo x) {
    int Must_Use_Specialization[fake_dependency<Foo>::value];
}

另见here for a live demo

答案 2 :(得分:5)

你必须依赖于Foo,如下所示:

int Must_Use_Specialization[-sizeof(Foo)];

答案 3 :(得分:3)

如果您永远不会使用它,则不需要基本模板!只为你想要使用的类型提供重载!

void func(int x) {
    printf("Hi 1\n");
}

void func(double x) {
    printf("Hi 2\n");
}

void func(Bar x) {
    printf("Hi 3\n");
}

这将导致func(foo);的编译时错误(除非foo可以转换为其他类型之一)。

答案 4 :(得分:1)

只需使用Boost.StaticAssert

即可

(编辑:或static_assert如果您有C ++ 11支持。我忘记了这一点。