在以下代码中:
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'
的模板参数
答案 0 :(得分:5)
C ++ 17 std::array
类模板参数推论(CTAD)
从C ++ 17开始,this new language feature是now 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