在以下代码中:
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 });
}
Run Code Online (Sandbox Code Playgroud)
如何避免在调用 b 时为 N 指定 2?为什么不能自动推导出这种类型?没有它我得到错误:
“b”:找不到匹配的重载函数“int b(int,const std::array &)”:无法推导出“N”的模板参数
从 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}));
Run Code Online (Sandbox Code Playgroud)
就我个人而言,我更喜欢在函数参数中使用std::span( 或) 。gsl::span
C++17std::array类模板参数推导(CTAD)
与C ++ 17日开始,这个新的语言功能是现在所使用的标准库,现在可以让我们省去了模板类型以及使以下工作:
主程序
#include <array>
int main() {
std::array a{1, 2, 3};
}
Run Code Online (Sandbox Code Playgroud)
代替 std::array<int, 3> a{1, 2, 3};
测试:
g++ -ggdb3 -O0 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp
Run Code Online (Sandbox Code Playgroud)
-std=c++14例如,如果我们改为设置,则无法编译:
error: missing template arguments before ‘a’
Run Code Online (Sandbox Code Playgroud)
在 Ubuntu 18.04、GCC 7.5.0 上测试。
模板参数推导依赖于实际参数和形式参数之间的直接类型匹配。实际参数是一个初始化列表。它与array类型不匹配(充其量它可以匹配 a 中的内部原始数组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 } );
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您N在编译时不是绝对需要,您可以使用std::initializer_list.
还有许多其他可能相关的方法(例如可变参数模板函数,或定义一个运算符来构建 a std::vector),但很难说哪种方法适合您未公开的目的。