【发布时间】:2014-09-06 00:53:27
【问题描述】:
现在我正在将我的项目从 Visual Studio 2008 迁移到 2013(未安装更新),但遇到了问题。
我有一种 Variant 类型,CData< T>,它具有到包含类型 T 的转换运算符。
template<class T> T& GetValue();
template<class T> const T& GetValue() const;
template<class T> T* GetValuePtr();
template<class T> const T* GetValuePtr() const;
template<class T> operator T&() { return GetValue<T>(); }
template<class T> operator const T&() const { return GetValue<T>(); }
template<class T> operator T*() { return GetValuePtr<T>(); }
template<class T> operator const T*() const { return GetValuePtr<T>(); }
CDataArray 类中有方法:
CData& Get(int Index) { return At(Index); }
const CData& Get(int Index) const { return operator [](Index); }
template<class T>
T& Get(int Index) { return At(Index).GetValue<T>(); }
template<class T>
const T& Get(int Index) const { return operator [](Index).GetValue<T>(); }
并且有人调用它:
Data::PDataArray SGQuests;
Data::PParams SGQuest = SGQuests->Get(i);
在这里,Data::PParams 将是 T。 在VS2008中,似乎使用了非常量非模板CDataArray::Get(),它返回了CData&,然后用非常量模板运算符T&()访问了这个CData&,最后返回了Data::PParams&。
在 VS2013 中,由于某种原因,它使用了 const 重载并导致错误:
1>PATH_TO_SRC\l1\data\type.h(126): error C2678: binary "=": no operator found that accepts left operand "const Ptr<Data::CParams>" (or there is no acceptable conversion)
1> PATH_TO_SRC\l1\data\ptr.h(29): may be "void Ptr<Data::CParams>::operator =(T *)"
1> with
1> [
1> T=Data::CParams
1> ]
1> PATH_TO_SRC\l1\data\ptr.h(28): or "void Ptr<Data::CParams>::operator =(const Ptr<Data::CParams> &)"
1> trying to match argument list "(const Ptr<Data::CParams>, const Ptr<Data::CParams>)"
1> PATH_TO_SRC\l1\data\type.h(125): compiling member function "void Data::CTypeImpl<T>::Copy(void **,void *const *) const" template class
1> with
1> [
1> T=const Ptr<Data::CParams>
1> ]
1> PATH_TO_SRC\l1\data\data.h(167): "Data::CTypeImpl<T>"
1> with
1> [
1> T=const Ptr<Data::CParams>
1> ]
1> PATH_TO_SRC\l1\data\data.h(97): "T &Data::CData::GetValue<T>(void)"
1> with
1> [
1> T=const Ptr<Data::CParams>
1> ]
1> PATH_TO_SRC\l3\quests\questmanager.cpp(307): "Data::CData::operator const T(void)<const Ptr<Data::CParams>>"
1> with
1> [
1> T=const Ptr<Data::CParams>
1> ]
我手动将消息翻译成英文,因此它们可能与原始 EN 编译器消息略有不同。
最后,如果我写明确的模板参数:
Data::PParams SGQuest = SGQuests->Get<Data::PParams>(i);
编译成功。
问题是:
- VS2013模板参数猜测与VS2008有什么不同?是否有任何地方(标准、文章或 smth)清楚地解释了为什么我的旧代码不应该编译?任何参考将不胜感激。
- 在这种情况下我应该如何编写代码?我现在是否必须显式编写模板参数,或者只是修改成员重载,或者安装一些更新?
附:最小代码可在 https://www.dropbox.com/s/zjohnu5v87tyr2c/ConstOverload.zip?dl=0 获得。完整的源代码在 https://code.google.com/p/deusexmachina/source/browse/branches/Dev/DEM/Src
【问题讨论】:
-
除了给我们一个指向您的整个代码库的链接之外,您能否将所有这些代码缩减为几个虚拟类,只使用几个会产生错误的函数?此外,名称查找是一项棘手的工作,而且您正在使用转换运算符,这是另一个复杂程度。我会担心,即使是可编译的 2008 版本也可能会调用我没想到的代码。
-
在您的最小示例中,您缺少
SimpleString.h和Hashtable.h。但是为什么有std::string的时候还需要另一个字符串类,现在有std::unordered_map的时候为什么还需要一个哈希表呢? -
我不打算运行这个示例,因为一个问题是编译时。只需尝试使用 Ctrl+F7 编译 Main.cpp,您将看到一个错误。为什么我更喜欢我自己的课程而不是 STL 是一个题外话,而且真的值得讨论吗?
-
我将一个问题缩小到另一个问题并问了另一个问题stackoverflow.com/questions/25818818/…。也许这个应该关闭。
标签: c++ templates visual-studio-2013 operator-overloading constants