2009-11-14 6 views
0

J'ai les lignes de code suivantes:erreur C2664 + classes génériques +/Wp64

p_diffuse = ShaderProperty<Vector4>(Vector4(1,1,1,1)); 
addProperty(&p_diffuse, "diffuse"); 

p_shininess = ShaderProperty<float>(10.0f); 
addProperty(&p_shininess, "shininess"); 

la fonction addProperty est mis en œuvre comme suit:

template <class A_Type> 
void IShader<A_Type>::addProperty(ShaderProperty<A_Type>* shaderProperty, 
            std::string propertyName) 
{ 
    m_shaderProperties[propertyName] = shaderProperty; 
} 

maintenant j'obtiens une erreur étrange du compilateur sur la dernière ligne du premier morceau de code. addProperty fonctionne très bien dans le premier cas, mais dans le second (en essayant d'ajouter p_shininess) je reçois:

error C2664: 'IShader<A_Type>::addProperty': cannot convert parameter 1 from 'ShaderProperty<A_Type> *' to 'ShaderProperty<A_Type> *' 

Huh !? un indice du problème pourrait être le suivant: si je vais dans les paramètres du projet et définir dans l'onglet général C++ "vérifier les problèmes de compatibilité 64 bits" de "non" à "oui (/ Wp64)" alors l'erreur se lit légèrement différent:

error C2664: 'IShader<A_Type>::addProperty': cannot convert parameter 1 from 'ShaderProperty<A_Type> *__w64 ' to 'ShaderProperty<A_Type> *' 

quoi de neuf ?? qu'est-ce que __w64 ??

modifier: définition de classe de IShader:

template <class A_Type> class IShader { 

public: 
virtual ~IShader(void) {}; 
virtual A_Type shade(IntersectionData* iData, Scene* scene) = 0; 

protected: 

ShaderProperty<A_Type>* getProperty(std::string propertyName); 
void addProperty(ShaderProperty<A_Type>* shaderProperty, std::string propertyName); 

private: 
std::map<std::string, ShaderProperty<A_Type>*> m_shaderProperties; 
}; 

Répondre

1

flotteur = Vector4!. Votre classe entière (IShader) est modélisée sur A_Type et pas seulement sur la méthode addProperty./Wp64 n'a rien à voir avec quoi que ce soit. La solution à ce problème nécessitera plus de contexte, vous voudrez peut-être définir addProperty pour être une fonction de membre modèle au lieu de IShader (ou en plus de) être modélisé.

Encore une fois cela sera difficile à obtenir sans savoir exactement ce que vous faites, mais je soupçonne que ce que vous voulez est une collection hétérogène de propriétés. Pour le faire en toute sécurité, vous devrez utiliser une vérification de l'exécution.

class ISharderProperty { 
    public: 
    virtual ~IProperty() {} 
}; 

template<typename ShadeType> 
class IShader; 

template <typename T> 
class ShaderProperty : public IShaderProperty { 
    IShader<T> *m_shader; 
    ... 
    }; 

template<typename ShadeType> 
class IShader { 
    ShadeType shade(...) = 0; 
    protected: 
     map<string, IShaderProperty*> m_shaderProperties; 
     template<typename T> 
     void addProperty(ShaderProperty<T>* prop, string name) { 
     m_shaderProperties[name] = prop; 
     } 
     template<typename T> 
     void getProperty(const string& name, ShaderProperty<T>** outProp) { 
     map<string, IShaderProperty*>::iterator i = m_shaderProperties.find(name); 
     *outProp = NULL; 
     if(i != m_shaderProperties.end()) { 
      *outProp = dynamic_cast<ShaderProperty<T>*>(*i); 
     } 
     } 
}; 

Vous devez utiliser getProperty comme

ShaderProperty<float> *x; 
ashader.getProperty("floatprop", &x); 
if(x) { 
    ... 
} 

Alternativement, getProperty pourrait retourner directement la valeur, mais vous devez mentionner T deux fois, par exemple

ShaderProperty<float> *x = ashader.getProperty<float>("floatprop"); 

if(x) { ... } 

Vous remarquerez que j'utilise dynamic_cast et vérifier NULL. Si vous avez un autre mécanisme pour mapper les noms de propriété aux types de propriétés, vous pouvez l'utiliser à la place et static_cast. Il y a un surcoût d'exécution associé à dynamic_cast.

+0

ah il semble que vous ayez raison .. mais comment dois-je définir la fonction addProperty alors? J'ai ajouté la définition de la classe IShader dans la description de problème. l'addProperty devrait permettre d'ajouter des propriétés de n'importe quel type générique à la carte m_shaderProperties – Mat

+0

Thx encore! mais l'IShader doit aussi être générique, car il a une fonction 'ombre' qui doit renvoyer une valeur générique (il peut y avoir des instances de shaders qui retournent float, d'autres retournent Vector4 et ainsi de suite). Chaque shader doit conserver une collection hétérogène de propriétés (comme vous l'avez supposé correctement). D'autre part, chaque propriété peut stocker le pointeur sur un Shader DE SON PROPRE TYPE GENERIQUE (so - shaders stocke des propriétés arbitraires - une propriété stocke un shader de son propre type). Cela me donne aussi le problème de l'inclusion mutuelle et j'ai besoin d'utiliser la déclaration forward d'une façon ou d'une autre ... – Mat

+0

Voir mon dernier pour savoir comment faire IShader et modéliser le forward afin que ShaderProperty puisse continuer à pointer vers un. –

Questions connexes