ошибка C2664 + универсальные классы + / Wp64 - PullRequest
0 голосов
/ 14 ноября 2009

У меня есть следующие строки кода:

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 ??

edit: определение класса 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 Ответ

1 голос
/ 14 ноября 2009

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.

связаны некоторые накладные расходы времени выполнения.
...