如何防止非专门化模板实例化

How to prevent non-specialized template instantiation?

本文关键字:实例化 专门化 何防止      更新时间:2023-10-16

我有一个模板化的class(称为Foo),它有几个专门化。如果有人试图使用Foo的非专门化版本,我希望编译失败。

下面是我实际得到的:

template <typename Type>
class Foo
{
  Foo() { cannot_instantiate_an_unspecialized_Foo(); }
  // This method is NEVER defined to prevent linking.
  // Its name was chosen to provide a clear explanation why the compilation failed.
  void cannot_instantiate_an_unspecialized_Foo();
};
template <>
class Foo<int>
{    };
template <>
class Foo<double>
{    };

:

int main()
{
  Foo<int> foo;
}
作品

:

int main()
{
  Foo<char> foo;
}

显然,编译器链只有在链接过程发生时才会报错。但是有没有办法让它提前抱怨呢?

我可以用boost

不要定义类:

template <typename Type>
class Foo;
template <>
class Foo<int> { };
int main(int argc, char *argv[]) 
{
    Foo<int> f; // Fine, Foo<int> exists
    Foo<char> fc; // Error, incomplete type
    return 0;
}

为什么这个工作?原因很简单,因为不是任何通用模板。

您可以简单地不定义基本大小写:

template <typename> class Foo;             // no definition!
template <> class Foo<int> { /* ... */ };  // Foo<int> is OK

c++ 0x的一个技巧(也可用于c++ 03 static_assert仿真,但错误消息不一定比保留未定义的主模板更好):

template<typename T>
struct dependent_false: std::false_type {};
template<typename Type>
struct Foo {
    static_assert( dependent_false<Type>::value
                 , "Only specializations of Foo may be used" );
};

断言只有在Foo用主模板实例化时才会触发。使用static_assert( false, ... )将始终触发断言。