2015-06-01 3 views
7

Wenn dies ein Duplikat ist, entschuldige ich mich. Ich schaute mich um und fand ähnliche Probleme, aber nichts genau so.Ist es möglich, Array-Größe aus einem Template-Argument zu extrahieren?

Wenn ich eine Vorlage wie so instanziiert ...

MyClass<int[10]> c; 

Wie kann ich schreiben die Vorlage Zugang zu bekommen sowohl die Art und die Array-Größe? Ich habe alles versucht, was ich mir vorstellen kann und ich kann es nicht bekommen.

Ich war von der std :: Funktionsvorlage inspiriert, die Sie den Funktionsprototyp verwenden ähnliche Syntax kann, wie ...

std::function<int(MyClass&)> myfunc; 

Also dachte ich, es wäre schön, etwas ähnliches für das Array haben und seine Größe. Ich kann jede der neuesten C++ - Funktionen (C++ 11/14) verwenden.

+1

Warum verwenden Sie nicht 'std :: array '? Es ist großartig und du solltest es verwenden ;-) – stefan

+0

@stefan: Nun, ich versuche, einer meiner Klassen etwas kontextabhängigen syntaktischen Zucker hinzuzufügen. Es hat nichts damit zu tun, dass ich tatsächlich Arrays benutze. – extracrispy

+0

Ist diese Syntax die einzige gültige Verwendung Ihrer Klasse oder ist es ein Sonderfall? – Quentin

Antwort

17

Sie können eine partielle Spezialisierung hinzufügen, die wie folgt aussieht:

template <typename T, ptrdiff_t N> 
class MyClass<T[N]> 
{ 
}; 

hier ein demo.

+3

Downvoter, was ist das Problem mit diesem Snippet? – Pradhan

+0

Sieht gut aus für mich. – Quentin

+1

Schön! Vielen Dank. Ich hatte so eine harte Zeit mit der Syntax, dass ich nichts funktionierte. – extracrispy

2
template <typename T, typename = void> 
struct deduce 
{ 
}; 

template <typename T> 
struct deduce<T, 
    typename ::std::enable_if< 
    ::std::is_array<T>{} 
    >::type 
> 
{ 
    using value_type = 
    typename ::std::decay<decltype(::std::declval<T>()[0])>::type; 

    static constexpr auto size = sizeof(T)/sizeof(value_type); 
}; 
+0

Ist das nicht völlig übertrieben? – Quentin

+3

Ja, nur für etwas Abwechslung. – user1095108

+3

"Overkill für Abwechslung". Ich mag das: p – Quentin

3
template<class Arr> 
struct array_size {}; 
template<class T, size_t N> 
struct array_size<T[N]>:std::integral_constant<std::size_t, N>{}; 
template<class Arr> 
struct array_element {}; 
template<class Arr> 
using array_element_t = typename array_element<Arr>::type; 
template<class T, size_t N> 
struct array_element<T[N]>{using type=T;}; 

jetzt können Sie array_size<ArrType>{} und array_element_t<ArrType> ohne den Typ Auspacken.