2009-12-25 6 views
3

J'essaye d'utiliser la spécialisation partielle de modèle sur une fonction (non-membre), et je suis en train de trébucher sur la syntaxe. J'ai recherché StackOverflow pour d'autres questions de spécialisation partielle de modèle, mais celles-ci traitent de la spécialisation partielle d'un modèle de fonction de classe ou de membre.Puis-je utiliser une spécialisation de modèle partiel pour une fonction (non-membre)?

Pour un point de départ, j'ai:

struct RGBA { 
    RGBA(uint8 red, uint8 green, uint8 blue, uint8 alpha = 255) : 
     r(red), g(green), b(blue), a(alpha) 
    {} 

    uint8 r, g, b, a; 
}; 

struct Grayscale { 
    Grayscale(uint8 intensity) : value(intensity) {} 

    uint8 value; 
}; 

inline uint8 IntensityFromRGB(uint8 r, uint8 g, uint8 b) { 
    return static_cast<uint8>(0.30*r + 0.59*g + 0.11*b); 
} 

// Generic pixel conversion. Must specialize this template for specific 
// conversions. 
template <typename InType, typename OutType> 
OutType ConvertPixel(InType source); 

je peux faire une spécialisation complète de ConvertPixel pour faire une RGBA à la fonction de conversion Niveaux de gris comme ceci:

template <> 
Grayscale ConvertPixel<RGBA, Grayscale>(RGBA source) { 
    return Grayscale(IntensityFromRGB(source.r, source.g, source.b)); 
} 

Je vais imaginer avoir plus de types de pixels qui offrent rouge, vert et bleu, mais peut-être dans un format différent, donc ce que je voudrais vraiment faire est une spécialisation partielle en spécifiant Grayscale pour OutType et encore permettre une variété de InType s. J'ai essayé une variété d'approches comme ceci:

template <typename InType> 
Grayscale ConvertPixel<InType, Grayscale>(InType source) { 
    return Grayscale(IntensityFromRGB(source.r, source.g, source.b)); 
} 

Mais le compilateur (Microsoft VS 2008 C++) rejette.

Est ce que j'essaye possible? Si oui, quelle est la bonne syntaxe? C++ ne permet pas une spécialisation partielle des modèles de fonction.

+1

vous ne pouvez pas. Utilisez la surcharge – KeatsPeeks

Répondre

5

Il est possible en utilisant la spécialisation de classe partitial:

template<class A, class B> 
struct Functor { 
    static A convert(B source); 
}; 

template<class B> 
struct Functor<GrayScale, B> { 
    static GrayScale convert(B source) { 
     return Grayscale(IntensityFromRGB(source.r, source.g, source.b)); 
    } 
}; 

// Common function 
template<class A, class B> 
A Convert(B source) { 
    return typename Functor<A,B>::convert(source); 
} 
+0

Excellent. Je vous remercie! –

7

Il ne permet même pas la spécialisation partielle des modèles de fonctions membres. Lorsque vous définissez une fonction qui fait partie d'une spécialisation partielle d'un modèle de classe, cela peut sembler un peu comme si vous aviez partiellement spécialisé la fonction membre. Mais tu ne l'as pas fait.

Herb Sutter discusses partial specialization

+0

Merci pour le lien! –

2

spécialisation partielle est un concept qui applique uniquement aux classes, fonctions non libres ou fonctions membres. Ce que vous voulez probablement faire, c'est juste fournir des surcharges de fonction (ou de fonction membre), qui sont en quelque sorte mappées à ce que font les spécialisations partielles et complètes pour les classes.