错误C2664 +泛型类+ / Wp64

时间:2009-11-14 18:16:51

标签: c++ generics floating-point compiler-errors

我有以下几行代码:

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

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

addProperty函数实现如下:

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

现在我在第一块代码的最后一行得到一个奇怪的编译器错误。 addProperty在第一种情况下工作正常,但在第二种情况下(当试图添加p_shininess时)我得到:

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

咦!? 一个问题的提示可能如下:如果我转到项目设置并在C ++常规选项卡中设置“检查64位兼容性问题”从“否”到“是(/ Wp64)”然后错误读取不同:

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

发生了什么事?什么是__w64 ??

编辑: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;
};

1 个答案:

答案 0 :(得分:1)

float!= Vector4。您的整个类(IShader)是在A_Type上模板化的,而不仅仅是addProperty方法。 / Wp64与任何事情无关。此问题的解决方案需要更多上下文,您可能希望将addProperty定义为模板成员函数,而不是模板化的IShader(或者除此之外)。

如果不确切知道自己在做什么,这将很难做到,但我怀疑你想要的是一个异构的属性集合。要安全地执行此操作,您需要使用一些运行时检查。

 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 );
         }
      }
 };

您必须使用像

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

或者,getProperty 可以直接返回值,但是你需要提两次T,例如

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

if( x ) { ... }

你会注意到我使用dynamic_cast并检查是否为NULL。如果您有一些其他机制可以将属性名称映射到属性类型,则可以使用该机制代替static_cast。与dynamic_cast相关联的运行时开销。