我有以下几行代码:
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;
};
答案 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 );
}
}
};
您必须使用像
这样的getPropertyShaderProperty<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
相关联的运行时开销。