array length deduction from argument

116 views Asked by At

Given a function with the parameter signature std::array<const size_t, V> shape like:

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

I need to always add the template parameter V like

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

as the braced-initializer list seems to be casted into a c++11 std::array. However, this seems to me redundant. The length of {2, 3} is two. I know it and the compiler should also know it. Is it possible to wrap it into:

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

I tried something like determining the size of the std::array as a constexpr. But I can't get rid of the template argument <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)>();
}

I add a runnable MWE here:

https://ideone.com/wrVe9M

This thread seems to be related but I do not see how it might help. Any suggestions?

1

There are 1 answers

1
max66 On BEST ANSWER

I suppose you can use a variadic make() function (make0() in the following example) that can calculate the size as sizeof...(Is)

The following is a full working example

#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;
 }