如何创建模板具有特定类型的编译时断言?

Wil*_*mKF 5 c++ templates compiler-errors

我有一个模板函数,并希望在编译时确保它没有在特定类的子类型或超类型上实例化.

如果违反此规则,如何导致C++编译器错误?

class base {
};
class derived : public base {
};
class lowest : public derived {
};

template <typename T>
bool isCorrect(const T& obj) {
  typedef foo<T> D;
  foo<T> *def = foo<T>::find();
  return (def && def->getAnswer(object));
}
Run Code Online (Sandbox Code Playgroud)

我想isCorrect只上课derived,但不是baselowest.请注意,可能有许多其他最低类和要排除的基类字符串以及可接受的替代派生类.

在C++中是否有一种方法可以将模板限制为仅应用于我明确指定的派生类?

Xeo*_*Xeo 9

特别是类型特征is_base_of.

#include <type_traits>

template <typename T>
bool isCorrect(const T& obj) {
  static bool const is_base = std::is_base_of<base, T>::value;
  static bool const derives = std::is_base_of<derived, T>::value;
  // specify allowed types here
  static bool const is_derived = std::is_same<T, derived>::value;
  // ---
  static_assert((!is_base && !derives) || is_derived, "wrong argument type");

  typedef foo<T> D;
  foo<T> *def = foo<T>::find();
  return (def && def->getAnswer(object));
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是特定于C++ 11的,但您可以使用Boost.TypeTraits获得相同的行为.


Jon*_*Jon 4

这是我所知道的一种技术。

首先,制作另一个模板类policy_enforcer。声明此类而不定义它,并且还提供它的特化,因为derived 它也已定义

template<typename T> struct policy_enforcer;
template<> struct policy_enforcer<derived> { };
Run Code Online (Sandbox Code Playgroud)

然后,在您想要锁定的函数中包含表达式sizeof(policy_enforcer<T>)。由于sizeof不完整类型是一个编译错误,这将阻止代码编译。

使用实时代码更新: usingbaseusingderivedusinglowest