static_assert su initializer_list::size()

static_assert su initializer_list::size()

Gli "elenchi di inizializzatori" sono solo orribili cianfrusaglie.

Non:

#include <initializer_list>

template<typename T>
void Dont(std::initializer_list<T> list) { // Bad!
    static_assert(list.size() == 3, "Exactly three elements are required.");
}

void Test() { Dont({1,2,3}); }

Fai:

template<typename T, std::size_t N>
void Do(const T(&list)[N]) { // Good!
    static_assert(N == 3, "Exactly three elements are required.");
}

void Test() { Do({1,2,3}); }

Il compilatore dice che il problema è init, non init.size().

Immagino che il costruttore possa essere chiamato da luoghi diversi con inizializzatori di lunghezza diversa.

(Per approfondire:stai cercando di scrivere un static_assert che dipende dal valore di runtime della variabile init , ovvero quanti elementi ha. static_assert s devono essere valutabili al momento della compilazione della funzione. Il tuo codice è analogo a questo esempio banalmente non valido :)

void foo(int i) { static_assert(i == 42, ""); }
int main() { foo(42); }  // but what if there's a caller in another translation unit?

Dalla mia discussione con @Evgeny, mi sono reso conto che funziona (con gcc 4.8 c++11 ) e può anche eseguire il controllo della dimensione accettando solo una dimensione compatibile nell'elenco degli inizializzatori (in main ).

(collegamento codice:http://coliru.stacked-crooked.com/a/746e0ae99c518cd6)

#include<array>
template<class T, int Length>
class Point
{
  public:
    Point(std::array<T, Length> init)
    {
//not needed//      static_assert(init.size() == Length, "Wrong number of dimensions");
    }
};

int main()
{
  Point<int, 3> q({1,2,3}); //ok
//  Point<int, 3> q2({1,2,3,4}); //compile error (good!)
  Point<int, 3> q2({1,2}); // ok, compiles, same as {1,2,0}, feature?
  return 0;
}