Static assert, enable if

0

Czy jesli szablon funkcji A ktory powinien miec static_assert / enable if wywoluje szablon funkcji B o identycznych wymaganiach co do static_assert / enable if to:

  1. pisac static_assert w obu - byloby chyba latwiej zrozumiec kod ?
  2. tylko w B
0

Ja bym dał w A, imho im szybciej failniesz tym lepiej.
A jeżeli B jest wywoływane jedynie z A to możesz nawet pominąć tego static asserta w B.

2

static_assert nie ma wpływu na SFINAE.
Po co obie rzeczy? Jeśli enebale_if jest prawidłowe, to static_assert z tym samym warunkiem też nie powinno zgłaszać błędu.
Może lepiej pokaż kod, z którym masz kłopot.

0

funkcja is_overflow jest wywolywana przez funkcje calculate; is_overflow ma identyczny warunek static_assert jak calculate, czy warto powielac warunki ? w koncu i tak calculate wywola is_overflow:

template<typename Smaller, typename Greater>
inline bool is_overflow(const Greater & x) {
   static_assert((numeric_limits<Greater>::is_integer || is_floating_point<Greater>::value) && "Number required.");
   return x < numeric_limits<Smaller>::lowest() || x > numeric_limits<Smaller>::max();
}

template <typename T>
template<typename Greater>
T Money<T>::calculate(const T & dollars, const long double & cents) {
   static_assert((numeric_limits<Greater>::is_integer || is_floating_point<Greater>::value) && "Number required.");
   cerr << __func__ << " TYPE_NAME = " << TYPE_NAME << ' ' << dollars << '\n';
   Greater amount_in_cents = Greater(dollars) * Greater(CENTS_PER_DOLLAR);
   T cents_round = dollars > 0 ? round(cents) : -round(cents);
   amount_in_cents += Greater(cents_round);
   cerr << __func__ << " amount_in_cents = " << amount_in_cents << '\n';
   if (! is_same<T, Integer>::value)
      if (is_overflow<T, Greater>(amount_in_cents))   //   call is_overflow with identical static_assert condition 
         throw out_of_range("amount_in_cents = " + std::to_string(amount_in_cents) + " is overflow for type " + TYPE_NAME);
   T result = T(amount_in_cents);
   return result;
}
0

2gie pytanie:
czy warto dodawac warunek if przed potencjalnym wywolaniem nie-inline funkcji (z ktorym to wiaze sie pewien narzut czasowy, ale ze sprawdzeniem warunku niestety takze (ale za to mniejszy narzut):

   template <typename Number,std::enable_if_t<is_floating_point<Number>::value 
                                 || is_integral<Number>::value, bool> = true>
   operator Number() const { 
      if (*this < numeric_limits<Number>::lowest() || *this > numeric_limits<Number>::max())
         throw out_of_range(" Integer " + string(*this) + " is out of range for type " + typeid(Number).name());
      Number number = 0;
      int_fast8_t power = 0;
      for (int_fast8_t i = MAX_ARRAY_LENGTH - 1; i >= 0; i--, power++) 
         if ((*this)[i] != 0)     /* to ten warunek, czy warto - w koncu pow() to nie inline,  (*this)[i] to short albo int_fast8_t 
zmieniany za pomoca using type = short */
            number += (*this)[i] * pow(10, power);
      if (this->signum == MINUS)
         number = -number;
      return number;  
   }
1

Nie lepiej liczyć **wszystko **w centach używając np. typu long int. Odpadła by wtedy cała ta żonglerka typami i szablonami.

2
teofrast napisał(a):

2gie pytanie:

czy warto dodawac warunek if przed potencjalnym wywolaniem nie-inline funkcji (z ktorym to wiaze sie pewien narzut czasowy, ale ze sprawdzeniem warunku niestety takze (ale za to mniejszy narzut):

Wygląda na to, że piszesz o mikrooptymalizacji, którą kompilator zignoruje.

Najlepszą metodą optymalizacji kodu jest zadbanie o niską złożoność czasową algorytmu.

Wszystko ponad to musi być operte o pomiary, które są trudne w przygotowaniu (tak by mierzyły to co trzeba). Można też analizować wygenerowany kod maszynowy, ale to jest jeszcze trudniejsze.
Mierzyć można nie tylko czas, ale też inne rzeczy (np cache miss), ale do tego trzeba mieć sporą wiedzę na temat tego jak działa hardware.

Edit:
używanie std::pow dla liczb całkowitych to jest jakaś pomyłka (obliczania zmiennoprzecinkowe są niedokładne i dużo wolniejsze od obliczeń na liczbach całkowitych). Doczytaj co to jest schemat Hornera i przemyśl jeszcze raz, czy to pow ma sens

1 użytkowników online, w tym zalogowanych: 0, gości: 1