将此模板static_assert代码扩展为覆盖子类 [英] Extending this template static_assert code to cover subclasses

查看:113
本文介绍了将此模板static_assert代码扩展为覆盖子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从上一个问题:

执行static_assert模板类型是另一个模板

Andy Prowl为我提供了此代码允许我 static_assert 表示模板类型是另一个模板类型:

Andy Prowl provided me with this code that allows me to static_assert that a template type is another template type:

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<foo,FooType>::value, ""); //success
};

int main(int,char**)
{
  bar<foo<int>> b;
  return 0;
}

这很好。

但这不适用于子类 foo< whatever>

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<foo,FooType>::value, ""); //fail
};

//Added: Subclass of foo<int>
struct foo_sub : foo<int> {
};

int main(int,char**)
{
  bar<foo_sub> b; //Changed: Using the subclass
  return 0;
}

Cany Prowl的 is_instantiation_of 代码扩展为允许子类?

Can Andy Prowl's is_instantiation_of code be extended to allow for subclasses?

推荐答案

KerrekSB在他的回答中写道,不能实现。

As KerrekSB wrote in his answer, an equally general extension of the solution you posted cannot be achieved.

但是,如果你放弃一点通用性,你可以写一个特定于 foo的类型trait (利用派生到基地是 在类型演绎期间执行的少数转换之一):

However, if it is OK for you to give up a bit of genericity, you can write a type trait specific for foo (exploiting the fact that derived-to-base is one of the few conversions that are performed during type deduction):

#include <type_traits>

template<typename T>
struct foo {};

template<typename T>
constexpr std::true_type test(foo<T> const&);

constexpr std::false_type test(...);

template<typename T>
struct is_instantiation_of_foo : public decltype(test(std::declval<T>())) { };

然后您可以这样使用:

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of_foo<FooType>::value, "");
};

struct foo_sub : foo<int> {
};

int main(int,char**)
{
  bar<foo_sub> b; // Will not fire
  return 0;
}

这里是 活动示例

这篇关于将此模板static_assert代码扩展为覆盖子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆