假设我有一个接口(interface)I
,以及一个实现该接口(interface)的模板类C
:
class I {
public:
virtual int foo() = 0;
};
template<typename T>
class C : public I {
public:
int foo() override;
};
我希望只有两个 C
实例,类型为 T1
和 T2
。我想为它们中的每一个专门化 foo()
。我可以在我的 .cpp
文件中执行此操作,如下所示:
template<>
C<T1>::foo() { return 1; }
template<>
C<T2>::foo() { return 2; }
template class C<T1>;
template class C<T2>;
我担心有人会提供更多他们想要用于 C
的模板参数,例如 T3
和 T4
,并且将定义一个通用的 foo()
template<typename T>
C::foo() { return 0; }
// (with appropriate specialization declarations)
template class C<T3>;
template class C<T4>;
因为在最后的场景中,有人可能会添加第五种类型,但忘记对其进行专门化 foo()
:
// forgotten:
// template<>
// C::<T5>::foo() { return 5; }
template class C<T5>;
如何要求编译器提示有人在单元测试或 C
实现中添加通用 foo()
?
最佳答案
您应该自己添加通用定义:
template<typename T>
int C<T>::foo() { static_assert(!std::is_same_v<T,T>, "Missing specialization of C<T>::foo()!"); return 0; }
由于 static_assert
的条件总是错误的,每个人都试图使用 C
尚未专门化的类型将得到静态断言错误(这还将额外提供有关如何解决此问题的有用提示)。
因为您已经提供了 C<T>::foo()
的定义任何试图提供 C<T>::foo()
的通用定义的人由于重新定义,会出现编译器错误。
请注意 static_assert
内的条件必须依赖于模板类型,以便仅在模板实例化时触发断言。
关于c++ - 我可以要求编译器禁止定义模板类成员函数的泛型版本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66119532/