检查模板参数是否从类继承

发布于 2024-10-18 20:55:28 字数 183 浏览 1 评论 0原文

我想检查赋予模板的类型是否是从我的项目中的基类继承的。

它应该像下面的示例中所期望的那样工作:

template< class T : public CBaseClass >
  • 是否可以使用模板来执行此操作,如果不能,我还能怎么做?

I want to check if the type given to a template is inherited from a base class in my project.

It should work like one would expect it from the following example:

template< class T : public CBaseClass >
  • Is it possible to do this with templates, if not, how else can I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柒夜笙歌凉 2024-10-25 20:55:28

以下 Stroustrup 的示例

template<class Test, class Base>
struct AssertSameOrDerivedFrom {
  AssertSameOrDerivedFrom() { &constraints; }
public:
  static void constraints() {
    Test *pd = 0;
    Base *pb = pd;
  }
};

template<class T>
struct YourClass {
  YourClass() {
    AssertSameOrDerivedFrom<T, CBaseClass>();
  }
};

在 C++0x 中,这变为:

template<class T>
struct YourClass {
  static_assert(std::is_base_of<CBaseClass, T>::value);
};

Following an example from Stroustrup:

template<class Test, class Base>
struct AssertSameOrDerivedFrom {
  AssertSameOrDerivedFrom() { &constraints; }
public:
  static void constraints() {
    Test *pd = 0;
    Base *pb = pd;
  }
};

template<class T>
struct YourClass {
  YourClass() {
    AssertSameOrDerivedFrom<T, CBaseClass>();
  }
};

In C++0x, this becomes:

template<class T>
struct YourClass {
  static_assert(std::is_base_of<CBaseClass, T>::value);
};
韵柒 2024-10-25 20:55:28

您可以将 Boost 中的 boost::is_base_and_drivenBOOST_STATIC_ASSERT 结合使用。如果您使用的是支持 TR1 或 C++0x 的编译器,则标准库中存在这些构造的等效项 (std::is_base_ofstatic_assert C++0x 中的语句)。

You can use boost::is_base_and_derived from Boost, combined with BOOST_STATIC_ASSERT. If you are using a compiler with TR1 or C++0x support, there are equivalents of those constructs in the standard library (std::is_base_of, and the static_assert statement in C++0x).

三生路 2024-10-25 20:55:28

如果你想断言,就按照努尔克的方式去做。如果要检查,请使用 boost 或 C++0x 中的 is_base_of 。如果您无法使用其中任何一个,请使用 SFINAE:

template < typename Base, typename PotentialDerived >
struct is_base
{
  typedef char (&no)  [1];
  typedef char (&yes) [2];

  static yes check(Base*);
  static no  check(...);

  enum { value = sizeof(check(static_cast<PotentialDerived*>(0))) == sizeof(yes) };
};

If you want to assert, do it Nurk's way. If you want to check, use is_base_of from boost or C++0x. If you can't use either of those, use SFINAE:

template < typename Base, typename PotentialDerived >
struct is_base
{
  typedef char (&no)  [1];
  typedef char (&yes) [2];

  static yes check(Base*);
  static no  check(...);

  enum { value = sizeof(check(static_cast<PotentialDerived*>(0))) == sizeof(yes) };
};
迷乱花海 2024-10-25 20:55:28

最简单的解决方案似乎是 std::is_base_of

static_assert(std::is_base_of_v<CBaseClass, T>);

您当然也可以将它与 if constexpr 结合使用:

if constexpr (std::is_base_of_v<CBaseClass, T>) {
    //
} else {
    //
}

有关更多详细信息,请参阅 cppreference:
https://en.cppreference.com/w/cpp/types/is_base_of

The simplest solution seems to be std::is_base_of:

static_assert(std::is_base_of_v<CBaseClass, T>);

You can of course also use it in combination with if constexpr:

if constexpr (std::is_base_of_v<CBaseClass, T>) {
    //
} else {
    //
}

See cppreference for more details:
https://en.cppreference.com/w/cpp/types/is_base_of

|煩躁 2024-10-25 20:55:28

越短越好:

template <typename Base, typename Derived>
struct is_base {
    constexpr static bool check(Base*)   { return true; }
    constexpr static bool check(...)     { return false; }
    enum { value = check(static_cast<Derived*>(0)) };
};

示例 1:

struct A {};
struct B  : A { };

int main(void) {
    static_assert(is_base<A,B>::value, "If Error: A is not base of B");
}

示例 2:

template <bool, typename T=void>
struct Use {
    static std::string info() { return "Implementation that consider that A is not base of B"; }
};

template <typename T>
struct Use<true,T>  {
    static std::string info() { return "Implementation that consider that A is the base of B"; }
};


int main(void) {
    std::cout << Use<is_base<A,B>::value>::info(); //Implementation that consider that A is the base of B
}

Shorter is better:

template <typename Base, typename Derived>
struct is_base {
    constexpr static bool check(Base*)   { return true; }
    constexpr static bool check(...)     { return false; }
    enum { value = check(static_cast<Derived*>(0)) };
};

Example 1:

struct A {};
struct B  : A { };

int main(void) {
    static_assert(is_base<A,B>::value, "If Error: A is not base of B");
}

Example 2:

template <bool, typename T=void>
struct Use {
    static std::string info() { return "Implementation that consider that A is not base of B"; }
};

template <typename T>
struct Use<true,T>  {
    static std::string info() { return "Implementation that consider that A is the base of B"; }
};


int main(void) {
    std::cout << Use<is_base<A,B>::value>::info(); //Implementation that consider that A is the base of B
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文