从参数中扣除数组长度

array length deduction from argument

给定一个参数签名为 std::array<const size_t, V> 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>();
}

我需要始终添加模板参数V like

auto t1 = make<2>({2, 3}); // does work but need the information twice
std::cout << t1.val() << std::endl;

因为大括号初始化器列表似乎被转换为 c++11 std::array。然而,这在我看来是多余的。 {2, 3} 的长度是二。我知道,编译器也应该知道。是否可以将其包装成:

// auto t0 = make({2, 3}); // doesn't work
// auto t0 = make(2, 3); // would be also ok

我尝试了一些方法,比如将 std::array 的大小确定为 constexpr。但我无法摆脱模板参数 <2>.

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)>();
}

我在这里添加一个可运行的MWE:

https://ideone.com/wrVe9M

thread 似乎是相关的,但我看不出它有什么帮助。 有什么建议吗?

我想你可以使用可变参数 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;
 }