统一类型和非类型模板参数 [英] Unify type and non-type template parameters

查看:45
本文介绍了统一类型和非类型模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类型特征,它检查给定类型是否是给定类模板的实例:

I have a type trait that checks if a given type is an instance of a given class template:

template <template <typename...> class C, typename T>
struct check_is_instance_of : std::false_type { };

template <template <typename...> class C, typename ...Ts>
struct check_is_instance_of<C, C<Ts...>> : std::true_type { };

template <template <typename...> class C, typename T>
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { };

不幸的是,这不适用于非类型模板参数,因为它们不会被可变参数模板参数捕获",所以

Unfortunately, this does not work for non-type template parameters as they are not "captured" by the variadic template parameters, so

is_instance_of<std::integral_constant, std::true_type>

产生编译错误.有什么方法可以编写 is_instance_of 的实现,该实现可用于任意数量的类型和非类型模板参数?

yields a compile-error. Is there any way to write an implementation of is_instance_of that works for an arbitrary number of type and non-type template parameters?

推荐答案

我认为没有一种干净的方法可以做到这一点除非,非类型参数都具有相同的类型,并且你知道它是哪种类型.在这种非常特殊的情况下,可以使用函数重载.

I don't think there is a clean way to do this unless the non-type arguments are all of the same type and you know which type it is. In that very specific case, function overloading can be used.

在任何其他情况下,您最终都会遇到完美转发问题的模板参数版本,在该模板变量版本中,您将必须专门处理每种类型/非类型参数组合.

In any other case, you end up in a template-argument version of the perfect forwarding problem where you would have to specialize for every type/nontype argument combination.

如果您只需要处理同类非模板参数,并且可以猜测类型,则应该可以执行以下操作.您可以为不同的类型重载instance_of(此处仅覆盖int),但是您必须为每种希望处理的类型显式创建一个实例:

If you only need to address homogeneous non-template arguments and you can guess the type, the following should work. You can overload instance_of for different types (only int is covered here), but you'd have to explicitly create an instance for each type you want to be able to handle:

// variation for non-type parameters, only for uniform parameters with
// known type.
template <typename V, template <V...> class C, typename T>
struct check_is_instance_of_nontype : std::false_type { };

template <typename V, template <V...> class C, V... Values>
struct check_is_instance_of_nontype<V, C, C<Values...>> : std::true_type { };

// this is as in your example
template <template <typename...> class C, typename T>
struct check_is_instance_of : std::false_type { };

template <template <typename...> class C, typename ...Ts>
struct check_is_instance_of<C, C<Ts...>> : std::true_type { };

template <template <typename...> class C, typename T>
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { };

template <template <typename...> class C, typename T>
constexpr bool instance_of()
{
    return is_instance_of< C, T>::value;
}

template <template <int...> class C, typename T>
constexpr bool instance_of()
{
    return check_is_instance_of_nontype< int, C, T>::value;
}

template< int... >
struct Duck
{
};

template<typename A, typename B>
struct Swallow
{

};

int main() {
    typedef Duck<1, 2> SittingDuck;
    typedef Swallow< int, int> UnladenSwallow;

    std::cout << instance_of< Duck, SittingDuck>() << instance_of< Swallow, UnladenSwallow>();
    return 0;
}

这篇关于统一类型和非类型模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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