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?
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With