如何解决如何仅将可变参数模板与模板模板参数匹配?
考虑以下代码:
#include <iostream>
template <template<class...> class C>
struct foo {
foo() { std::cout << "base case\n";}
};
template <template<class> class C>
struct foo< C > {
foo() { std::cout << "single param case\n";}
};
template <template<class,class> class C>
struct foo< C > {
foo() { std::cout << "two param case\n";}
};
template <typename T> struct bar1 {};
template <typename T,typename U> struct bar2 {};
template <typename T,typename U,typename V> struct bar3 {};
template <typename...T> struct barN {};
int main() {
foo<bar1> f;
foo<bar2> g;
foo<bar3> h;
foo<barN> n;
}
single param case
two param case
base case
base case
假设给定barX
,并且我还有其他带有不同类型参数的模板。有些可变的,有些没有。
是否可以编写仅与可变参数模板(在上面的示例中为barN
)相匹配的专门化语言?
解决方法
非常有趣的问题。不幸的是,答案是否定的。 没有通用的方法来确定模板是具有模板参数包还是带有或没有默认值的一堆常规模板参数。
原因是非可变模板可以绑定到可变参数模板模板参数,而模板的具体类型可以绑定到模板参数包。
因此,实际上无法通过演绎/专业化获得信息。一般来说,这很好-如果没有此功能,可变参数模板将失去很多功能。
但是,如果我们可以限制模板参数的最大长度,则可以编写具有一系列模板特化特征的特征。之所以有效,是因为部分排序(如您的问题所示):godbolt
,我们可以通过对0参数实例化的参数进行计数,来确定可以使用0个模板参数实例化的类模板是真正的可变参数还是(仅)所有非变量模板参数都具有默认值:
values
然后,我们可以使用它构建一组专门化,分别接受可变参数的,1-参数(可能具有默认值)和2-参数(可能具有默认值)的类模板:
template<class> constexpr unsigned argc_v;
template<template<class...> class C,class... A> constexpr unsigned argc_v<C<A...>> = sizeof...(A);
template<template<class...> class,class = void> constexpr bool is_variadic_v = false;
template<template<class...> class C> constexpr bool is_variadic_v<C,std::void_t<C<>>> = argc_v<C<>> == 0;
对于稍后的template<template<class...> class,class = std::true_type>
struct foo;
template<template<class...> class C>
struct foo<C,std::bool_constant<is_variadic_v<C>>> {
foo() { std::cout << "variable case\n"; }
};
template<template<class> class C>
struct foo<C,std::bool_constant<!is_variadic_v<C> && argc_v<C<void>> == 1>> {
foo() { std::cout << "single param case\n";}
};
template<template<class,class> class C>
struct foo<C,std::bool_constant<!is_variadic_v<C> && argc_v<C<void,void>> == 2>> {
foo() { std::cout << "two param case\n";}
};
测试是必要的(在C ++ 20模式下),我感到有些失望。我认为是something to do with P0522 / CWG150。
Demo。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。