查找是否可以使用一组参数实例化 class 模板,arity-wise(在 C++17 中)
Finding if a class template can be instantiated with a set of arguments, arity-wise (in C++17)
我有一个模板,它带有一个模板模板参数和一组类型参数。我只想在参数匹配时用参数实例化模板。像这样:
// 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 说:
error: 'T' does not refer to the name of a parameter pack
fantasized that it would be as simple as this:
不……没那么简单……当你写的时候
using type = std::conditional_t<can_apply_t<Template, Args...>,
Template<Args...>,
void>;
当 conditional_t
的测试为假时,Template<Args...>
也必须是可接受的类型。
您需要一个 can_apply_t
可以直接 return 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...>;
};
如果你能使用 C++20,概念 会让事情变得容易得多。
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...>;
};
我有一个模板,它带有一个模板模板参数和一组类型参数。我只想在参数匹配时用参数实例化模板。像这样:
// 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 说:
error: 'T' does not refer to the name of a parameter pack
fantasized that it would be as simple as this:
不……没那么简单……当你写的时候
using type = std::conditional_t<can_apply_t<Template, Args...>,
Template<Args...>,
void>;
当 conditional_t
的测试为假时,Template<Args...>
也必须是可接受的类型。
您需要一个 can_apply_t
可以直接 return 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...>;
};
如果你能使用 C++20,概念 会让事情变得容易得多。
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...>;
};