我有以下几行代码:
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_cast
。 dynamic_cast
有一些运行时开销。