C++ 从参数推导数组长度
给定一个参数签名为std::array shape的函数,如下所示:C++ 从参数推导数组长度,c++,c++11,templates,variadic-templates,stdarray,C++,C++11,Templates,Variadic Templates,Stdarray,给定一个参数签名为std::array shape的函数,如下所示: template<int V> struct Cls {int val(){return V;} }; template <int V> auto make(std::array<const size_t, V> shape) -> Cls<V>{ return Cls<V>(); } 因为带括号的初始值设定项列表似乎被转换成c++11std::arr
template<int V>
struct Cls {int val(){return V;} };
template <int V>
auto make(std::array<const size_t, V> shape) -> Cls<V>{
return Cls<V>();
}
因为带括号的初始值设定项列表似乎被转换成c++11std::array
。然而,在我看来,这似乎是多余的。{2,3}
的长度是2。我知道,编译器也应该知道。是否可以将其包装为:
// auto t0 = make({2, 3}); // doesn't work
// auto t0 = make(2, 3); // would be also ok
我尝试了一些类似于将std::array
的大小确定为constepr
。但是我无法摆脱模板参数
模板
constexpr size\u t arr\u len(std::array){return V;}
模板
自动生成2(V形)->Cls
这似乎有关联,但我看不出有什么帮助。
有什么建议吗?我想您可以使用一个可变的make()
函数(make0()
,在下面的示例中),该函数可以将大小计算为sizeof…(Is)
下面是一个完整的工作示例
#include <array>
#include <iostream>
template<int V>
struct Cls {int val(){return V;} };
template <int V>
auto make(std::array<const size_t, V> shape) -> Cls<V>{
return Cls<V>();
}
template <typename ... Is>
auto make0 (Is ... is) -> Cls<sizeof...(Is)>
{ return make<sizeof...(Is)>({ {std::size_t(is)... } }); }
int main ()
{
auto t1 = make0(2, 3, 5, 7);
std::cout << t1.val() << std::endl;
}
#包括
#包括
模板
结构Cls{int val(){return V;}};
模板
自动生成(标准::数组形状)->Cls{
返回Cls();
}
模板
自动生成0(Is…Is)->Cls
{返回make({{std::size_t(is)…}});}
int main()
{
自动t1=make0(2,3,5,7);
std::无法查找std::initializer\u list
。使用它而不是std::array
。您可以使用std::make\u tuple
?至于为什么这不起作用:编译器如何知道{2,3}
只能是长度为2的std::array
?必须有专门针对std::array
的黑客攻击。为什么应该std::initializer\u list
帮助?为什么应该std::make\u tuple
帮助?两者都有误导性。我试图用可变模板解决它,但没有成功。在查看您的解决方案后这似乎是显而易见的。
template <int V>
constexpr size_t arr_len(std::array<const size_t, V>){return V;}
template <typename V>
auto make2(V shape) -> Cls<arr_len(shape)>{
return Cls<arr_len(shape)>();
}
#include <array>
#include <iostream>
template<int V>
struct Cls {int val(){return V;} };
template <int V>
auto make(std::array<const size_t, V> shape) -> Cls<V>{
return Cls<V>();
}
template <typename ... Is>
auto make0 (Is ... is) -> Cls<sizeof...(Is)>
{ return make<sizeof...(Is)>({ {std::size_t(is)... } }); }
int main ()
{
auto t1 = make0(2, 3, 5, 7);
std::cout << t1.val() << std::endl;
}