C ++运算符重载分辨率模糊

时间:2009-04-25 00:10:19

标签: c++ templates gcc

我试图将古老的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匹配时遇到问题,那么这是有意义的,但是,为什么它试图将它强制转换为本机类型然后执行算术运算? 请帮帮我。

提前致谢。

3 个答案:

答案 0 :(得分:4)

第二个操作数类型是long [int]。我希望第一个是TypeValue,但是没有运算符*采用这两种确切类型。但是,该运算符还有许多其他类型组合,编译器可以通过对第一个操作数进行隐式转换来选择。该语言允许编译器执行此操作以尝试查找匹配项。

但它应该选择多少次转换?编译器无法选择int是否优于long int。 (你可能会争辩说,因为第二个操作数是long int,所以它应该是首选的转换目标,但这不是事情的工作方式。)

所以,一些建议:首先,不要提供这么多的隐式转换。由于该课程只能保留longdoublestring,因此这是我提供的唯一三次转化。仅这一点可能无法解决您的问题,但它可能会减少错误输出的大小并使其他事情更易于管理。

而不是将(index - first_index)转换为long类型,请考虑将其转换为T类型(即TypeValue),因为这似乎是您真正想要的操作首先执行。

答案 1 :(得分:2)

我会将所有转换运算符更改为命名函数,以便:

operator long() const;

变为

long ToLong() const;

通过强制转换操作符进行的隐式转换会导致各种问题,而我自己的编程标准也禁止它们使用。

答案 2 :(得分:0)

我们需要知道什么是T.看起来你正在使用某种类型(例如unsigned char)实例化XVector,它可以转换成你看到的所有类型,并且编译器不知道哪个一个可供选择。