统一类型和非类型模板参数

10

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

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>> { };

很不幸,这对非类型模板参数不起作用,因为它们不被可变模板参数“捕获”,所以

is_instance_of<std::integral_constant, std::true_type>
产生了编译错误。是否有一种方法可以编写一个实现任意数量类型和非类型模板参数的is_instance_of的函数?

这不是你问题的答案,但这个实现不能与模板模板别名一起使用。也许这正是你想要的,但也可能不是。 - TartanLlama
1个回答

4
我认为没有干净的方法来做这件事,除非非类型参数都是相同类型的并且你知道它是哪种类型。在这种非常特殊的情况下,可以使用函数重载。
在任何其他情况下,你会遇到完美转发问题的模板参数版本,其中你将不得不为每个类型/非类型参数组合进行特化。
如果你只需要处理同类的非模板参数,并且你可以猜测类型,那么以下代码应该有效。你可以为不同的类型(仅此处包括int)重载instance_of,但你必须明确地为你想要处理的每种类型创建一个实例:
// 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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接