【发布时间】:2009-04-25 00:10:19
【问题描述】:
我正在尝试将一个古老的 C++ 代码库从 gcc 3.2 迁移到 gcc 4.1,因为我遇到了一些问题。在所有问题中,以下问题让我一无所知(我想我在 Java 上花了太多时间,或者我可能忘记了 C++ 的基础知识:-P)。
我有一个模板类
template < class T > class XVector < T >
{
...
template < class T > T
XVector < T >::getIncrement ()
{
...
}
template < class T > int
XVector < T >::getValue (size_t index, T& value)
{
...
//The problematic line
value = (T) (first_value + getIncrement())
* (long) (index - first_index);
....
}
}
此类基于 STL std::vector。我有第二类 TypeValue,它的定义如下,它可以保存 int、long 及其无符号变体、float、double、std::string 之一。还重载了几乎所有可能的运算符。
class TypeValue
{
union
{
long* _int_value;
double* _real_value;
string* _text_value;
} _value;
TypeValue();
explicit TypeValue(long _long);
explicit TypeValue(int _int);
explicit TypeValue(unsigned long _ulong);
...
//similarly for all the remaining supported types.
TypeValue(const TypeValue& ) //Copy constructor
virtual TypeValue& operator=(const TypeValue &rhs);
TypeValue& operator+ (TypeValue& )const;
TypeValue& operator* (TypeValue& )const;
...
//For all the basic operators
operator long() const;
operator int() const;
operator unsigned long() const;
operator unsigned int() const;
...
}
最后我有了另一个类,我们称之为 build_breaker,它创建一个对象为XVector < TypeValue > a_variable;。现在,当我在 gcc 3.2 上编译它时,它编译没有任何问题。但是,当我尝试在 gcc 4.1 上编译它时,我收到错误消息,称 operator* 在类 XVector 中存在模棱两可的过载,而候选人是
如果编译器说它在找到 T * long 的匹配项时遇到问题,那是有道理的,但是,它为什么要尝试将其类型转换为本机类型,然后执行算术运算? 请帮我解决这个问题。
提前致谢。
【问题讨论】:
-
您的算术运算符应该接受并返回 const 引用,因为它们是 const 函数。你的赋值运算符应该接受一个 const 引用,但是让方法本身是 const 没有多大意义;它是一个赋值运算符,所以它应该修改你调用它的东西。
-
稍微更正,赋值运算符声明为
不是纯虚,而是有方法定义。virtual TypeValue& operator=(const SdmsTypedValue &rhs); -
不要在 cmets 中“更正”它。通过编辑您的问题并使其正确来真正纠正它。当你这样做时,还请记住我们以前从未见过“SdmsTypedValue”;这是你第一次提到这种类型。
-
Rob,我已经更新了代码。对不起 SdmsTypedValue。这就是复制粘贴的效果。我想我需要提高我的代码审查技能。
-
Niel & Gorpik 认为发生了太多隐式转换并造成严重破坏。我进一步查看了代码,发现运算符 * 与 int 和 size_t 一起用作右侧类型。如果一种类型被重载,则其他引用在找到正确的调用时会遇到问题。所以我不得不为 RHS 上的所有类型重载 operator*。虽然它解决了问题,但我不确定这是否是这个问题的最佳解决方案。因为我没有其他开发人员追随我,对我的逻辑摸不着头脑。请提出建议。