2016-09-17 3 views
0

Ich versuche, eine Vorlagenklasse zu definieren, die einige Operationen für einen Typ hat. Die Methode ToString sollte implementiert werden, um den ToString im Namespace eines beliebigen Typs aufzurufen, mit dem die Werkzeugvorlagenklasse instanziiert wurde.Aufruf der Funktion mit dem gleichen Namen wie die Methode

namespace X 
{ 
    class SomeType 
    { 
    }; 

    std::wstring ToString(SomeType) 
    { 
     // ... 
    } 
} 

template<class T> 
class Tools 
{ 
    static auto ToString(T& t) 
    { 
     return ToString(t); 
    } 
} 

Ich bekomme einen Fehler in der Tools-Implementierung von ToString. Der Compiler versucht, die Methode ToString erneut rekursiv aufzurufen, anstatt die ToString im Namespace X aufzurufen.

Ich kann X :: ToString nicht verwenden, da dies fehlschlägt, wenn ich die Tools-Klasse mit einem Typ aus Namespace Y instanziiere ZB wenn ich folgendes nutze:

namespace Y 
{ 
    class SomeOtherType 
    { 
    }; 

    std::wstring ToString(SomeOtherType) 
    { 
     // ... 
    } 
} 

Y::SomeOtherType someOtherType; 
auto s = Tools<Y::SomeOtherType>::ToString(someOtherType); // Would fail as SomeOtherType isn't in namespace X. 

Ist es möglich, dass dies funktioniert?

Ich verwende VS 2015 Update 3. Eine Lösung, die dafür arbeitet, wird bevorzugt.

Verwandte: calling a global function with a class method with the same declaration

+1

Ich sehe nicht, warum 'X :: ToString()' wird nicht funktionieren können Sie ein Beispiel dafür, was Sie meinen? – Galik

+1

@Galik: Er meint, er will 'namespaceof (T) :: ToString()'. es könnte auch 'Y :: ToString()' oder 'Z :: ToString()' oder etwas anderes sein. Es ist also nicht richtig, 'X :: ToString()' zu schreiben. –

+0

Wenn ich richtig verstehe (nicht sicher), scheint es, dass Sie wollen, dass 'X :: ToString();' mit verschiedenen Parametertypen ('X :: SomeType' &' Y :: SomeType') aufgerufen werden kann. Dazu müssen Sie es zu einer Template-Funktion machen. – Galik

Antwort

3

Ok, ich könnte eine Lösung. Fügen Sie eine Zwischenfunktion, die sich außerhalb der Klasse befindet, mit einem anderen Namen hinzu, der dann mit dem richtigen Namen aufruft. In

namespace ImplementationDetail 
{ 
    template< class T > 
    auto ToStringHelper(T& t) 
    { 
     return ToString(t); 
    } 
} 

template<class T> 
class Tools 
{ 
    auto ToString(T& t) 
    { 
     return ImplementationDetail::ToStringHelper(t); 
    } 
} 
+0

Das scheint vernünftig. Abgesehen davon ist dies einer der Gründe, warum ich die Religion "mache alles eine freie Funktion" nicht unterschreibe; Eine Mitgliedsfunktion von 'T' wäre hier außerordentlich einfach und klar gewesen. –

+0

@LightnessRacesinOrbit. Ja, ich stimme zu. Ich habe vergessen zu erklären, dass die T-Typen eigentlich Enums sind, zu denen ich keine Methoden hinzufügen kann. –

+0

Gute Sachen dann :) –

2

Explizit

return ::X::ToString(t); 

verwenden die Funktion im X Namespace zu verweisen, unabhängig davon, welcher Namespace die Referenz herkommt.

+1

Hmm, ja, aber das Aufrufen einer Funktion im X-Namespace, unabhängig davon, in welchem ​​Namespace es sich befindet, wird nicht viel genutzt, wenn die Funktion in einem Y-Namespace ist. –

Verwandte Themen