Deduce std :: array size?

时间:2016-10-08 14:29:07

标签: 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 });
}

如何避免在对N的b调用中指定2?为什么不能自动推断出这种类型呢?没有它我得到错误:

  

'b':找不到匹配的重载函数'int b(int,const   std :: array&amp;)':无法推断'N'

的模板参数

3 个答案:

答案 0 :(得分:5)

C ++ 17 std::array类模板参数推论(CTAD)

从C ++ 17开始,this new language featurenow used by the standard library,现在允许我们也省略模板类型,以便进行以下工作:

main.cpp

#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上进行了测试。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

为了推断"C:\WINDOWS\system32\inetsrv\rewrite.dll" (reference) Go to "Programs and Features" (Win+X, F) and repair "IIS URL Rewrite Module 2". "C:\WINDOWS\system32\inetsrv\aspnetcore.dll" (reference) Go to "Programs and Features" (Win+X, F) and repair "Microsoft .NET Core 1.0.0 - VS 2015 Tooling ...". 大小,你可以使用通用lambdas(C ++ 14):

std::array

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); } (它在库基础知识TS中)将由编译器实现(或者您将使用some own实现它)时,您还不需要传递数组构建时的大小,只需使用

std::make_array