2017-12-07 3 views
2

Wie kann ich die Vorlage für allgemeine ArrayC-like Array Template-Spezialisierung

template <class T, std::size_t N> 
struct Data<T[N]> {} 

in einer Art und Weise zu schreiben, dass ich es Elemente ist durch [] Operator (oder sonstwie) zugreifen kann?

#include <fstream> 
#include <iostream> 
#include <sstream> 
#include <utility> 

template <typename T> 
struct Data; 

template <typename T> 
std::ostream& operator<<(std::ostream& os, const Data<T>& val) { 
    return val(os); 
} 

template <typename T> 
Data<std::remove_cv_t<T>> data(const T& val) { return { val }; } 

template <> 
struct Data<int> { 
    std::ostream& operator()(std::ostream& os) const { 
     os << val; 
     return os; 
    } 
    const int& val; 
}; 

template <class T, std::size_t N> 
struct Data<T[N]> { 
    std::ostream& operator()(std::ostream& os) const { 
     for (std::size_t i = 0; i < N; i++) { 
      os << data(val[i]); 
     } 
     return os; 
    } 
    T val; 
}; 

Fehler beim Zugriff auf:

error: subscripted value is not an array, pointer, or vector 
        os << data(val[i]); 
           ^~~ ~ 

Es scheint, dass ich <T[N]> für so etwas wie <T(&)[N]> ändern sollte Bezug für das Array zu fangen, aber ich kann es nicht funktioniert. Oder vielleicht die T val; sollte in T* val; sein, weil das Array zum Zeiger degeneriert, so dass ich es "fangen" kann?

EDIT 1

Für T val[N]; der Fehler ist:

error: cannot initialize an array element of type 'int' with an lvalue of type 'int const[2]' 
Data<std::remove_cv_t<T>> data(const T& val) { return { val }; } 
                ^~~ 

EDIT 2

Als ich

template <typename T, size_t N> 
struct Data<std::array<T, N> > 

dann zu verwenden versuchen, es entspricht keiner Vorlage.

error: implicit instantiation of undefined template 'PrettyPrint::Data<int [2]>' 
    sstream << PrettyPrint::data(val); 
      ^
+0

Ich habe den Fehler von 'T val [N]' hinzugefügt. – Davar

+0

Innerhalb 'Daten ' 'T' ist' int', nicht 'int [42]'. –

+0

Also wie kann ich Typ für Int [42] formulieren? – Davar

Antwort

1

Die richtige Vorlage war

template <typename T, std::size_t N> 
struct Data<T[N]> { 
    std::ostream& operator()(std::ostream& os) const { 
     for (std::size_t i = 0; i < N; i++) { 
      os << data(val[i]); 
     } 
     return os; 
    } 
    const T(&val)[N]; 
}; 

Was für den Grund const T(&val)[N]; ist? Ich denke darüber nach, die Referenz im Gegensatz zu Array-Degeneration als Zeiger abzufangen, aber ich wäre wirklich froh, wenn mir jemand das genauer erklären würde.