查找是不是可以使用一组参数实例化类模板,arity-wise(在 C++17 中)
Posted
技术标签:
【中文标题】查找是不是可以使用一组参数实例化类模板,arity-wise(在 C++17 中)【英文标题】:Finding if a class template can be instantiated with a set of arguments, arity-wise (in C++17)查找是否可以使用一组参数实例化类模板,arity-wise(在 C++17 中) 【发布时间】:2021-12-31 16:17:00 【问题描述】:我有一个模板,它接受一个模板模板参数和一组类型参数。我只想在参数匹配时才用参数实例化模板。像这样的:
// can_apply_t = ???
template<template<typename...> typename Template, typename... Args>
struct test
using type = std::conditional_t<can_apply_t<Template, Args...>, Template<Args...>, void>;
;
template<typename> struct unary_template;
template<typename, typename> struct binary_template;
static_assert(std::is_same_v< test<unary_template, int>::type, unary_template<int> >);
static_assert(std::is_same_v< test<binary_template, int>::type, void >);
我幻想它会像这样简单:
template<template<typename... T> typename Template, typename... Args>
struct test
using type = std::conditional_t<sizeof...(T) == sizeof...(Args), Template<Args...>, void>;
;
...但是 clang++12 说:
错误:'T' 不是指参数包的名称
【问题讨论】:
sizeof...(T)
需要一组类型,而不是一组 class K,class V,...
(不存在且无法推断)。
【参考方案1】:
幻想会这么简单:
不...没有那么简单...当你写作时
using type = std::conditional_t<can_apply_t<Template, Args...>,
Template<Args...>,
void>;
当conditional_t
的测试为假时,Template<Args...>
也必须是可接受的类型。
你需要一个can_apply_t
,在可能的情况下直接返回Template<Args...>
,否则void
。
我建议如下
template <template <typename...> class C, typename... Ts>
auto can_apply_f (int)
-> std::remove_reference_t<decltype(std::declval<C<Ts...>>())>;
template <template <typename...> class C, typename... Ts>
auto can_apply_f (long) -> void;
template <template <typename...> class C, typename ... Ts>
using can_apply_t = decltype(can_apply_f<C, Ts...>(0));
template <template<typename...> typename Template, typename... Args>
struct test
using type = can_apply_t<Template, Args...>;
;
【讨论】:
【参考方案2】:如果你可以使用 C++20,concepts 会让事情变得更容易。
template<template<typename...> typename, typename...>
struct test
using type = void;
;
template<template<typename...> typename Template, typename... Args>
requires requires typename Template<Args...>;
struct test<Template, Args...>
using type = Template<Args...>;
;
Demo.
【讨论】:
...我现在在 yomm2 中所做的许多其他事情也是如此,但我想暂时保持与 C++17 的兼容性。以上是关于查找是不是可以使用一组参数实例化类模板,arity-wise(在 C++17 中)的主要内容,如果未能解决你的问题,请参考以下文章