如何使用参数包和非类型模板值执行部分模板专业化?
How to perform partial template specialization with a parameter pack and non-type template value?
在尝试 时,我编写了这个部分模板专业化:
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {}; //(2)
当我尝试使用 Test1
和 Test2
的部分模板专业化时,这会导致编译错误 <Expression> has incomplete type and cannot be defined
;因此——据我所知——用法 (3) 与定义 (2) 不匹配:
int main() {
Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a; // (3)
}
虽然我不明白为什么会这样。在试验该示例时,我意识到当我 'hiding' 我的 any_type
结构中参数包的内容时会发生这种情况:
#include <array>
template <auto f> struct any_type;
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {};
template <typename array_wrapper> struct Test2;
template <int... A> struct Test2<any_type<std::get<0>(A...)>> {};
template <typename array_wrapper> struct Test3;
template <int A> struct Test3<any_type<A>> {};
int main() {
//Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a;
//Test2<any_type<1>> b;
Test3<any_type<1>> ok;
}
测试 1 和测试 2 失败并出现同样的错误,测试 3 工作正常。为什么在前两种情况下部分模板特化 'fail'?据我了解,声明提供了 'interface' 以便使用该结构,并且专业化中的参数与实际提供的参数相匹配。
代码
可以找到代码 here.
编译选项:
我使用 g++-10.0 (GCC) 10.0.1 20200124 (experimental)
并通过 g++ -std=c++2a file.cc
编译,需要 c++2a 因为我使用非类型模板参数。
模板参数可以从一组有限的模式中推导出来。对于模板非类型参数,该集合只是(来自 [temp.deduct.type]/8):
type[i]
template-name<i>
(其中模板名称指的是 class 模板)
TT<i>
...就是这样。您的 Test3
匹配第二种形式,而其他两个根本不匹配。
尚不清楚 Test2
示例的工作原理。 Test1
示例可能是我们想要考虑的东西,因为非类型模板参数的使用在 C++20 之后激增,但它不是当前有效的东西。
在尝试
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {}; //(2)
当我尝试使用 Test1
和 Test2
的部分模板专业化时,这会导致编译错误 <Expression> has incomplete type and cannot be defined
;因此——据我所知——用法 (3) 与定义 (2) 不匹配:
int main() {
Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a; // (3)
}
虽然我不明白为什么会这样。在试验该示例时,我意识到当我 'hiding' 我的 any_type
结构中参数包的内容时会发生这种情况:
#include <array>
template <auto f> struct any_type;
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {};
template <typename array_wrapper> struct Test2;
template <int... A> struct Test2<any_type<std::get<0>(A...)>> {};
template <typename array_wrapper> struct Test3;
template <int A> struct Test3<any_type<A>> {};
int main() {
//Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a;
//Test2<any_type<1>> b;
Test3<any_type<1>> ok;
}
测试 1 和测试 2 失败并出现同样的错误,测试 3 工作正常。为什么在前两种情况下部分模板特化 'fail'?据我了解,声明提供了 'interface' 以便使用该结构,并且专业化中的参数与实际提供的参数相匹配。
代码 可以找到代码 here.
编译选项:
我使用 g++-10.0 (GCC) 10.0.1 20200124 (experimental)
并通过 g++ -std=c++2a file.cc
编译,需要 c++2a 因为我使用非类型模板参数。
模板参数可以从一组有限的模式中推导出来。对于模板非类型参数,该集合只是(来自 [temp.deduct.type]/8):
type[i]
template-name<i>
(其中模板名称指的是 class 模板)TT<i>
...就是这样。您的 Test3
匹配第二种形式,而其他两个根本不匹配。
尚不清楚 Test2
示例的工作原理。 Test1
示例可能是我们想要考虑的东西,因为非类型模板参数的使用在 C++20 之后激增,但它不是当前有效的东西。