我试图将古老的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
中的{{1}}和候选者
operator*(long int, long int) operator*(int, long int) operator*(long unsigned int, long int) operator*(unsigned int, long int) operator*(double, long int) operator*(float, long int)
如果编译器说找到T * long匹配时遇到问题,那么这是有意义的,但是,为什么它试图将它强制转换为本机类型然后执行算术运算? 请帮帮我。
提前致谢。
答案 0 :(得分:4)
第二个操作数类型是long [int]
。我希望第一个是TypeValue
,但是没有运算符*
采用这两种确切类型。但是,该运算符还有许多其他类型组合,编译器可以通过对第一个操作数进行隐式转换来选择。该语言允许编译器执行此操作以尝试查找匹配项。
但它应该选择多少次转换?编译器无法选择int
是否优于long int
。 (你可能会争辩说,因为第二个操作数是long int
,所以它应该是首选的转换目标,但这不是事情的工作方式。)
所以,一些建议:首先,不要提供这么多的隐式转换。由于该课程只能保留long
,double
和string
,因此这是我提供的唯一三次转化。仅这一点可能无法解决您的问题,但它可能会减少错误输出的大小并使其他事情更易于管理。
而不是将(index - first_index)
转换为long
类型,请考虑将其转换为T
类型(即TypeValue
),因为这似乎是您真正想要的操作首先执行。
答案 1 :(得分:2)
我会将所有转换运算符更改为命名函数,以便:
operator long() const;
变为
long ToLong() const;
通过强制转换操作符进行的隐式转换会导致各种问题,而我自己的编程标准也禁止它们使用。
答案 2 :(得分:0)
我们需要知道什么是T.看起来你正在使用某种类型(例如unsigned char)实例化XVector,它可以转换成你看到的所有类型,并且编译器不知道哪个一个可供选择。