2017-11-13 3 views
1

ich viele verschiedene Funktionen haben, die ganz ähnliche Operationen der Fall ist, wo die Art und die Größe durch die Funktionsnamen codiert wird wie folgt aus:Abgeleitet typenames

int * operation_0_0_i(int a) { 
    int * result = new int[4]; 
    /* ... */ 
    return result; 
} 
int * operation_0_1_i(int a) { 
    int * result = new int[8]; 
    /* ... */ 
    return result; 
} 

float * operation_0_0_f(float a) { 
    float * result = new float[4]; 
    /* ... */ 
    return result; 
} 

float * operation_0_1_f(float a) { 
    float * result = new float[4]; 
    /* ... */ 
    return result; 
} 

Statt mit diesem zum Verwechseln Menge verschiedener Funktionen Ich dachte über die Verwendung von Vorlagen nach. Mein erster Versuch, wo structs Templat, abgeleiteten Typ zu realisieren:

template< typename T > 
struct A { 
    using type = T; 
    using array = std::array< T, 4 >; 
}; 

template< typename T > 
struct B { 
    using type = T; 
    using array = std::array< T, 8 >; 
}; 

Damit ich so etwas tun:

template< class U, typename T > 
T* operation0(T a) { 
    typename U<T>::array a; 
    /* ... */ 
    return a.data(); // I know, that this is unsafe. Its just for this example                      
} 

template< class U, typename T > 
T* operation1(T a) { 
    typename U<T>::array a;                      
    /* ... */ 
    return a.data(); 
} 

int main() { 
    int * res1 = operation1<A, int>(3); 
    int * res2 = operation2<B, int>(8); 
    /* ... */ 
    return 0; 
} 

Leider ist dieses nicht kompiliert. Das g ++ sagt mir, dass

In function ‘T* operation0(T)’: error: expected nested-name-specifier before ‘U’ typename U<T>::array a; 

Offensichtlich ist der Typname Specifier an dieser Position falsch. Aber wenn ich diesen Spezifizierer löschen, klagt g ++, dass

‘U’ is not a template U<T>::array a; 

Hat jemand weiß, was ich falsch mache? Und gibt es vielleicht einen noch besseren Ansatz, vielleicht mit std::variant? Vielen Dank für Ihre Zeit;)

Mit freundlichen Grüßen

+0

Haben Sie auch einen Blick in die „Nicht-Typ Template-Parameter“? – AndyG

Antwort

3

Sie sagen müssen, dass Ihre U-Klassen-Template ist und nehmen Sie 1 Parameter:

template<template <class > class U, typename T > 
T* operation0(T _a) { 
    typename U<T>::array a; 
    /* ... */ 
    return a.data();                
} 
Verwandte Themen