【问题标题】:Code compiled in VS2008 doesn't in VS2013, const overloadingVS2008编译的代码VS2013没有,常量重载
【发布时间】: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);

编译成功。

问题是:

  1. VS2013模板参数猜测与VS2008有什么不​​同?是否有任何地方(标准、文章或 smth)清楚地解释了为什么我的旧代码不应该编译?任何参考将不胜感激。
  2. 在这种情况下我应该如何编写代码?我现在是否必须显式编写模板参数,或者只是修改成员重载,或者安装一些更新?

附:最小代码可在 https://www.dropbox.com/s/zjohnu5v87tyr2c/ConstOverload.zip?dl=0 获得。完整的源代码在 https://code.google.com/p/deusexmachina/source/browse/branches/Dev/DEM/Src

【问题讨论】:

  • 除了给我们一个指向您的整个代码库的链接之外,您能否将所有这些代码缩减为几个虚拟类,只使用几个会产生错误的函数?此外,名称查找是一项棘手的工作,而且您正在使用转换运算符,这是另一个复杂程度。我会担心,即使是可编译的 2008 版本也可能会调用我没想到的代码。
  • 在您的最小示例中,您缺少 SimpleString.hHashtable.h。但是为什么有std::string的时候还需要另一个字符串类,现在有std::unordered_map的时候为什么还需要一个哈希表呢?​​
  • 我不打算运行这个示例,因为一个问题是编译时。只需尝试使用 Ctrl+F7 编译 Main.cpp,您将看到一个错误。为什么我更喜欢我自己的课程而不是 STL 是一个题外话,而且真的值得讨论吗?
  • 我将一个问题缩小到另一个问题并问了另一个问题stackoverflow.com/questions/25818818/…。也许这个应该关闭。

标签: c++ templates visual-studio-2013 operator-overloading constants


【解决方案1】:

通过向 CData 添加第三个重载解决了这个问题

template<class T> operator const T&() { return GetValue<T>(); }

原解决方案贴在: Conversion operator error C2678 in VS2013, works in VS2008

在此处查看可能的更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多