![](/img/trans.png)
[英]How to deduce array size out of std::array<T, N>::pointer member/dependent type?
[英]Deduce std::array size?
在以下代码中:
template<size_t N>
int b(int q, const std::array<int, N>& types)
{
int r = q;
for (int t : types)
{
r = r + t;
}
return r;
}
int main()
{
b<2>(9, { 2,3 });
}
如何避免在为 N 调用 b 时必须指定 2? 为什么不能自动推导出这种类型? 没有它我得到错误:
“b”:没有匹配重载 function 找到“int b(int,const std::array &)”:无法推断“N”的模板参数
C++17 std::array
类模板参数推导(CTAD)
从 C++17 开始, 这个新的语言特性现在被标准库使用,现在允许我们省略模板类型,以便以下工作:
主程序
#include <array>
int main() {
std::array a{1, 2, 3};
}
而不是std::array<int, 3> a{1, 2, 3};
测试:
g++ -ggdb3 -O0 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp
例如,如果我们设置-std=c++14
,它将无法编译:
error: missing template arguments before ‘a’
在 Ubuntu 18.04、GCC 7.5.0 上测试。
模板参数推导依赖于实际参数和形式参数之间的直接类型匹配。 实际参数是一个初始化列表。 它与array
类型不匹配(充其量它可以匹配std::array
中的内部原始std::array
,但语言规则不支持)。
相反,您可以只使用原始数组,即:
#include <stddef.h>
#include <array>
template<size_t N>
int b(int q, int const (&types)[N] )
{
int r = q;
for (int t : types)
{
r = r + t;
}
return r;
}
int main()
{
b( 9, { 2, 3 } );
}
或者,如果您在编译时不是绝对需要N
,则可以使用std::initializer_list
。
还有许多其他可能相关的方法(例如可变参数模板函数,或定义一个运算符来构建std::vector
),但很难说哪种方法适合您未公开的目的。
要推导出std::array
大小,您可以使用通用 lambdas (C++14):
auto b = [](int q, const auto& types) {
int r = q;
for (int t : types)
{
r = r + t;
}
return r;
};
int main() {
std::array<int, 2> arr = {{2,3}};
b(9, arr);
}
当std::make_array
(它在库基础 TS 中)将由编译器实现(或者您将使用它的一些自己的实现)时,您在构造时也不需要传递数组大小,只需使用
b(9, std::make_array(2,3));
从 C++20 开始,我们可以使用std::to_array()
进行类型和大小推导。
在你的情况下:
int b(int q, const auto& types)
{
int r = q;
for (int t : types)
{
r = r + t;
}
return r;
}
b(9, std::to_array({2, 3}));
// --- or ---
b(9, std::to_array<int>({2, 3}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.