2010-12-04 7 views
3

Ich möchte eine Funktion mit dieser Schnittstelle.Wie deklariert man eine Template-Funktion mit einem optionalen Kompilierzeitparameter?

func<Type1,CompileOption>(Type2 value) 
//or 
func<Type1>(Type2 value) 

Der erste Parameter für die Kompilierzeit ist ein Typ. Dies ist bei jedem Funktionsaufruf erforderlich.
Der zweite Kompilierzeitparameter ist optional. Es wird verwendet, um das Verhalten von func zu ändern.
Die Funktion selbst wird auf den regulären Parametertyp (Type2) eingestellt.

Kann eine Schnittstelle wie diese gebaut werden?

Wenn es nicht möglich ist, gibt es eine Möglichkeit, ähnliches Verhalten zu erhalten? zB etwas, das wie eine Template-Funktion funktioniert, die zwei Parameter für die Kompilierung benötigt, wobei die zweite optional ist?

Der naive Ansatz funktioniert nicht.

// invalid syntax 
template< typename Type1, typename CompileOption = Default, typename Type2> 
void func(Type2 t2); 

// Does the wrong thing. 
// CompileOption Parameter now change Type2. 
template< typename Type1, typename Type2, typename CompileOption = Default> 
void func(Type2 t2); 

//This kinda expresses what I'm looking for 
template<typename Type2> 
template<typename Type1, typename Optional = Default > 
void func(Type2 t2); 
+1

Die erste Option ist keine ungültige Syntax. Angenommen, Sie verwenden einen C++ 0x-Compiler (da Sie scheinbar Standard-Template-Argumente in Funktionsschablonen verwenden dürfen), können Sie auch Standardargumente für nicht nachgestellte Template-Parameter verwenden. –

Antwort

0

Ich dachte über das Problem nach und verwirrte alle anderen auch. Es ist nicht möglich, eine Funktion zu schreiben, es sei denn, C++ 0x-Erweiterungen werden verwendet. Es ist jedoch ziemlich einfach, es mit zwei überladenen Funktionen zu schreiben.

template< typename Type1, typename Option, typename Type2 > 
void func(Type2 t2) 
{ /* ... */ } 

template< typename Type1, typename Type2 > 
void func(Type2 t2) 
{ func<Type1,Default,Type2>(t2); } 

func<int,fast_t>(20.f); 
func<float>(30); // uses Default as Option 
func<float,Default>(30); //exact same call as above. 
1

Meinst du sowas?

template<typename Type1, typename Type2, typename Option> 
void foo (Type2 arg) 
{ 
    ... code ... 
} 

template<typename Type1, typename Type2> 
void foo (Type2 arg) 
{ 
    foo<Type1, Type2, DefaultOption>(arg); 
} 

Edit: Die obige Snippet funktioniert, hat aber den Nachteil, dass Typ2 explizit in den Aufrufen angegeben werden muss.

Ich muss zugeben, dass ich nicht eine gute vollständige Vorlage Lösung dafür denken kann; in der Nähe konnte ich wurde mit leeren Methodenargumente erhalten:

struct DefaultOption { ... } DEFAULT; 
struct OtherOption { ... } OTHER; 

template<typename Type1, typename Type2, typename Option> 
void foo (Type2 arg, Option) 
{ 
    ... code ... 
} 

template<typename Type1, typename Type2> 
void foo (Type2 arg) 
{ 
    foo<Type1, Type2>(arg, DEFAULT); 
} 

Dies ermöglicht Anrufe in Form

foo<std::string>(1, DEFAULT); 
foo<std::string>(1.0, OTHER); 
foo<std::string>("Hello"); 

Ich bin neugierig, was die wirkliche Antwort auf dieses Rätsel ist.

+0

Nah dran was ich will aber nicht ganz. Es möchte in der Lage sein, 'foo' so zu nennen:' foo (42) 'oder' foo (42.f) '. –

+0

In der Tat. Ich habe meine Antwort entsprechend bearbeitet, aber leider ist es immer noch nicht so, wie Sie es sich vorgestellt haben. – Lars

+3

Können Sie die Reihenfolge der Vorlagenargumente nicht ändern? 'Vorlage '? – UncleBens

1

könnten Sie versuchen immer

template<typename Type1, typename Optional = Default > 
struct A 
{ 
    template<typename Type2> 
    void func(Type2 t2) { 
     // function body 
    } 
}; 

Vielleicht ist es das, was Sie brauchen.