2009-11-14 89 views
0

我有下面的代碼行:錯誤C2664 +泛型類+/Wp64

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位兼容性問題」中從「no」設置爲「yes(/ 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

浮=的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 可以直接返回值,但隨後你需要提牛逼的兩倍,例如

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

if(x) { ... } 

你會注意到我使用dynamic_cast並檢查NULL。如果您有其他一些機制將屬性名稱映射到屬性類型,則可以使用該機制,並使用static_cast。有一些與dynamic_cast相關的運行時間開銷。

+0

啊似乎你是對的..但我該如何定義addProperty函數呢?我在問題描述中添加了IShader類的定義。 addProperty應該允許將任何泛型類型的屬性再次添加到m_shaderProperties地圖 – Mat 2009-11-14 18:43:15

+0

Thx!但是IShader也需要是通用的,因爲它有一個需要返回一個通用值的「陰影」函數(可以有返回浮動的着色器實例,其他的返回Vector4等等)。每個着色器應保持不同的屬性集合(如您所假設的那樣)。另一方面,每個屬性都可以將指針存儲到一個它自己的通用類型着色器(所以着色器存儲任意屬性 - 一個屬性存儲它自己類型的着色器)。這也給了我相互包含的問題,並且需要使用前向聲明...... – Mat 2009-11-14 19:27:18

+0

請參閱我的最新版本,瞭解如何使IShader模板化並轉發decalre,以便ShaderProperty可以繼續指向一個指針。 – 2009-11-14 19:47:12