Idiomatic way of calculating a template parameter depending on other parameters

I am looking for an idiomatic way to optimize this template that I wrote.

My main problem is how to correctly define a template parameter nand use it as a return parameter, while the user should not overwrite it.

I am also open to other suggestions on how to write this template in the C ++ 14 idiomatic style.

template<
  typename InType=uint32_t,
  typename OutType=float,
  unsigned long bits=8,
  unsigned long n=(sizeof(InType) * 8) / bits
>
std::array<OutType,n> hash_to_color(InType in) noexcept {    
  InType mask = ~0;
  mask = mask << bits;
  mask = ~mask;
  std::array<OutType,n> out;
  auto out_max = static_cast<OutType>((1 << bits) - 1);
  for (auto i = 0; i < n; i++) {
    auto selected = (in >> (i * bits)) & mask;
    out[i] = static_cast<OutType>(selected) / out_max;
  }
  return out;
}
+4
source share
2 answers

As for the template parameter n, you can avoid it by using it autoas the return type in C ++ 14. Here's a simpler example of the principle:

template<int N>
auto f()
{
    constexpr int bar = N * 3;   
    std::array<int, bar> foo;
    return foo;
}

, .

( ++ 11) trailing-return-type:

template<int N>
auto f() -> std::array<int, N * 3>
{

, ++ 14, return.

: ~0 , 0 int, ~(InType)0. (1 << bits) - 1 .

+3

, .. , .

, , n, 3 n, , n 2 + 3 n + 1. , , , .

  • - auto, , .

  • - - DRY.

( , , M.M.)

, , constexpr:

#include <array>

constexpr int arr_size(int n) { return n * n + 3 * n + 1; }

constexpr, :

template<int N>
std::array<int, arr_size(N)> f() {
    return  std::array<int, arr_size(N)>();
}

, , arr_size .

:

int main() {
    auto a = f<10>();
    a[0] = 3;
}
+2

Source: https://habr.com/ru/post/1656433/


All Articles