推导出 std::array 大小?

pau*_*ulm 8 c++ c++14

在以下代码中:

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”的模板参数

Coo*_*Cmd 8

从 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


Cir*_*四事件 7

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 上测试。

  • 遗憾的是我们不能*仅*省略大小参数。在MSVC 15.9上试过了,不行。 (5认同)
  • 之间有什么东西吗?扣除尺寸,但不扣除类型?因为我希望它是 uint8_t 而不是 int,否则会被扣除,显式 uint8_t 文字也很棘手/混乱。 (2认同)

Che*_*Alf 5

模板参数推导依赖于实际参数和形式参数之间的直接类型匹配。实际参数是一个初始化列表。它与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),但很难说哪种方法适合您未公开的目的。