我有以下几行代码:

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

最佳答案

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_castdynamic_cast有一些运行时开销。

10-08 15:57