2017-08-08 1 views
0

Betrachten Sie den folgenden Code ein:Wie spezialisieren/überladen Sie eine Funktion für gleiche Template-Parametertypen?

class Helper { 
public: 
    template<typename taResult, typename taParam> static taResult Cast(const taParam par); 
}; 
template<> inline __m256d Helper ::Cast(const __m256i par) { 
    return _mm256_castsi256_pd(par); 
} 
template<> inline __m256i Helper ::Cast(const __m256d par) { 
    return _mm256_castpd_si256(par); 
} 

ich zum Helper eine Funktion hinzugefügt werden soll Abgüsse behandeln, in denen die Parameter und die Rückgabetypen Gleichen sind. Alle meine Versuche, sich soweit zu spezialisieren/überladen, sind bei verschiedenen Kompilierungsfehlern fehlgeschlagen.

So etwas wie die folgenden in der Klasse Körper:

template<typename T> static T Cast(const T par) { 
    return par; 
} 
+1

Es sieht aus wie der Code einige seiner Vorlage Argumente verloren, wenn hier kopiert werden; Kannst du bestätigen, dass es korrekt ist? –

+0

@DanielH: OP verwendete Spezialisierungen. – Jarod42

+0

Also, warum nicht hier normale Überladung verwenden? Sie stellen 3 Überladungen zur Verfügung: die eine, die __m256i nimmt, die eine, die __m256d nimmt, und die normale Vorlage, die Sie mit Ihrem generischen Algorithmus verwenden. –

Antwort

3

Sie können nicht partiell spezialisieren Funktion, und Ihre Überlastung wäre mehrdeutig.

Sie können Klasse hinzufügen, die Sie teilweise mit Spezialisierung obwohl kann:

template <typename To, typename From> struct CastImpl; 

template <typename T> struct CastImpl<T, T> 
{ 
    T operator()(T t) const { return t; } 
}; 

template <> struct CastImpl<__m256d, __m256i> 
{ 
    __m256d operator()(__m256i t) const { return _mm256_castsi256_pd(t); } 
}; 

template <> struct CastImpl<__m256i, __m256d> 
{ 
    __m256i operator()(__m256d t) const { return _mm256_castpd_si256(t); } 
}; 

und dann

class Helper { 
public: 
    template<typename taResult, typename taParam> 
    static taResult Cast(const taParam par) 
    { 
     return CastImpl<taResult, taParam>{}(par); 
    } 
}; 
+0

Warum ist die teilweise Spezialisierung einer Funktion nicht erlaubt? –

+2

@DanielH, weil es [mit Funktionsüberlastung vermasselt] (http://www.gotw.ca/publications/mill17.htm). –

+0

OP voll spezialisiert seine Funktion, das ist erlaubt. – Jarod42

1

Nein, Sie können nicht, denn das ist ein Versuch wäre, die teilweise eine Funktion spezialisiert, was nicht erlaubt ist. Stattdessen müssten Sie eine Zwischenvorlagenklasse verwenden, die spezialisiert werden kann.

Ich kann bei Bedarf Beispiel bereitstellen.

1

Sie einen Helfer Klasse/Struktur Vorlage verwenden können Helper::Cast zu implementieren.

Hier ist ein einfaches Programm, das ein paar Abkürzungen verwendet, um das Konzept zu demonstrieren.

using __m256d = double; 
using __m256i = int; 

template<typename taResult, typename taParam> struct RealHelper; 

class Helper 
{ 
    public: 
     template<typename taResult, typename taParam> static taResult Cast(const taParam par) 
     { 
     return RealHelper<taResult, taParam>::doit(par); 
     } 

    private: 

}; 

template <> struct RealHelper<__m256d, __m256i> 
{ 
    inline static __m256d doit(const __m256i par) 
    { 
     // return _mm256_castsi256_pd(par); 
     return par; 
    } 
}; 

template <> struct RealHelper<__m256i, __m256d> 
{ 
    inline static __m256i doit(const __m256d par) 
    { 
     // return _mm256_castpd_si256(par); 
     return par; 
    } 
}; 

template <typename T> struct RealHelper<T, T> 
{ 
    inline static T doit(const T par) 
    { 
     return par; 
    } 
}; 

int main() 
{ 
    auto v1 = Helper::Cast<int, double>(10); 
    auto v2 = Helper::Cast<double, int>(20); 
    auto v3 = Helper::Cast<int, int>(30); 
    auto v4 = Helper::Cast<double, double>(40); 
} 
0

Ich möchte die Helfer eine Funktion hinzuzufügen Abgüsse zu behandeln, in denen die Parameter und die Rückgabetypen Gleichen sind.

Was SFINAE mit einer Cast() Version gemäß dem Wert von std::is_same<taResult, taParam>::value aktivieren/deaktivieren?

Ein vereinfachtes Beispiel

#include <iostream> 
#include <type_traits> 

struct Helper 
{ 
    template <typename taR, typename taP> 
    static std::enable_if_t<false == std::is_same<taR, taP>::value, taR> 
     Cast (taP const & par) 
    { std::cout << "different Cast" << std::endl; return {}; } 

    template <typename taR, typename taP> 
    static std::enable_if_t<true == std::is_same<taR, taP>::value, taR> 
     Cast (taP const & par) 
    { std::cout << "equal Cast" << std::endl; return par; } 
}; 

template <> 
int Helper::Cast<int, long> (long const & par) 
{ std::cout << "int/long Cast" << std::endl; return {}; } 

template <> 
long Helper::Cast<long, int> (int const & par) 
{ std::cout << "long/int Cast" << std::endl; return {}; } 

int main() 
{ 
    Helper::template Cast<int>(0);  // print "equal Cast" 
    Helper::template Cast<int>(0L);  // print "int/log Cast" 
    Helper::template Cast<long>(0);  // print "long/int Cast" 
    Helper::template Cast<long>("foo"); // print "different Cast" 
} 
+0

Es gibt einen Kompilierungsfehler, wenn ich Versuchen Sie 'Cast()' für bestimmte Typen zu spezialisieren (wie '__m256d' und' __m256i' in meinem Codebeispiel in der Frage). –

+0

@SergeRogatch - modifiziertes Beispiel mit ein paar Spezialisierungen – max66

Verwandte Themen