简体   繁体   English

二进制运算符在模板类上重载

[英]Binary operator overloading on a templated class

I was recently trying to gauge my operator overloading/template abilities and as a small test, created the Container class below. 我最近试图测量我的运算符重载/模板能力,并作为一个小测试,创建下面的Container类。 While this code compiles fine and works correctly under MSVC 2008 (displays 11), both MinGW/GCC and Comeau choke on the operator+ overload. 虽然此代码编译良好并且在MSVC 2008(显示11)下正常工作,但MinGW / GCC和Comeau都在operator+过载时阻塞。 As I trust them more than MSVC, I'm trying to figure out what I'm doing wrong. 因为我比MSVC更信任他们,所以我想弄清楚我做错了什么。

Here is the code: 这是代码:

#include <iostream>

using namespace std;

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
   public: void setobj(T ob);
     T getobj();
      private: T obj;
};

template <typename T>
void Container<T>::setobj(T ob)
{
   obj = ob;
}

template <typename T>
T Container<T>::getobj()
{
   return obj;
}

template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
{
      Container<T> temp;
      temp.obj = lhs.obj + rhs.obj;
      return temp;
}

int main()
{    
    Container<int> a, b;

 a.setobj(5);
    b.setobj(6);

 Container<int> c = a + b;

 cout << c.getobj() << endl;

    return 0;
}

This is the error Comeau gives: 这是Comeau给出的错误:

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 27: error: an explicit template argument list is not allowed
          on this declaration
  Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
               ^

1 error detected in the compilation of "ComeauTest.c".

I'm having a hard time trying to get Comeau/MingGW to play ball, so that's where I turn to you guys. 我很难让Comeau / MingGW去打球,所以我转向你们。 It's been a long time since my brain has melted this much under the weight of C++ syntax, so I feel a little embarrassed ;). 很长一段时间以来,我的大脑在C ++语法的重压下融化了这么多,所以我觉得有点尴尬;)。

EDIT : Eliminated an (irrelevant) lvalue error listed in initial Comeau dump. 编辑 :消除了初始Comeau转储中列出的(不相关的)左值错误。

I found the solution thanks to this forum posting . 由于这个论坛发帖,我找到了解决方案。 Essentially, you need to have a function prototype before you can use 'friend' on it within the class, however you also need the class to be declared in order to properly define the function prototype. 基本上,你需要有一个函数原型才能在类中使用'friend',但是你还需要声明这个类才能正确定义函数原型。 Therefore, the solution is to have two prototype definitons (of the function and the class) at the top. 因此,解决方案是在顶部有两个原型定义(功能和类)。 The following code compiles under all three compilers: 以下代码在所有三个编译器下编译:

#include <iostream>

using namespace std;

//added lines below
template<typename T> class Container;
template<typename T> Container<T> operator+ (Container<T>& lhs, Container<T>& rhs); 

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
      public: void setobj(T ob);
              T getobj();
      private: T obj;
};

template <typename T>
void Container<T>::setobj(T ob)
{
      obj = ob;
}

template <typename T>
T Container<T>::getobj()
{
      return obj;
}

template <typename T>
Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
{
      Container<T> temp;
      temp.obj = lhs.obj + rhs.obj;
      return temp;
}

int main()
{    
    Container<int> a, b;

    a.setobj(5);
    b.setobj(6);

    Container<int> c = a + b;

    cout << c.getobj() << endl;

    return 0;
}
template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)

Here the "<>" after operator+ should be removed since you're just declaring a new template, not specializing a general one. operator+之后的“<>”应该被删除,因为您只是声明一个新模板,而不是专门的一般模板。 Also at least g++ wants to see the template declaration before the friend declaration, so it needs to be moved before the declaration of Container . 此外,至少g++想要在友元声明之前看到模板声明,因此需要在声明Container之前移动它。 So the following order of the declarations works: 所以声明的以下顺序有效:

// forward declaration of Container<T>
template <typename T>
class Container;

template <typename T>
Container<T> operator+(Container<T>& lhs, Container<T>& rhs)
{ ... }

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
      ...
};

I gave this a shot under GCC and got it to compile and run with a few changes. 我在GCC下给了它一个镜头并让它编译并运行一些更改。 There were two changes I had to make to get GCC happy. 为了让GCC满意,我必须做出两个改变。

One was the declaration of the friend template function. 一个是朋友模板功能的声明。 It is its own template declaration separate from the class one, so I used U instead of the Container class' T there. 它是自己的模板声明,与第一类分开,因此我使用U而不是Container类'T. I also got rid of the <> after the operator+. 我也在运算符+之后摆脱了<>。 I don't think you'd need those unless you're writing a template specialization. 除非你正在编写模板专业化,否则我认为你不需要这些。

      template<typename U>
      friend Container<U> operator+ (Container<U>& lhs, Container<U>& rhs);

Two, the line 二,行

Container<int>& c = a + b;

didn't fly with GCC because you're asking to store a reference to a temporary (the result of the addition). 没有与GCC一起飞行,因为你要求存储对临时的引用(添加的结果)。 I removed the ampersand so that there is a place to store the result. 我删除了&符号,以便有一个存储结果的地方。

I saw your post just now, that also works because of the forward declarations. 我刚看到你的帖子,因为前向声明也有效。 I guess I'll post this anyway as an alternative that doesn't require them. 我想我会发布这个作为不需要它们的替代方案。 Of course I only tested in GCC... 当然我只在GCC测试过......

You'd be better off defining the function directly in the class. 你最好直接在类中定义函数。 Also, you should pass the parameters as const references. 此外,您应该将参数作为const引用传递。

template <typename T>
class Container
{
public:
    friend Container operator+ (Container const & lhs, Container const & rhs)
    {
        // ...
    }
};

'operator+' is not a member function, and it's not templated. 'operator +'不是成员函数,它不是模板化的。 It's just the operator+ which takes templated parameters.' 它只是运算符+,它采用模板化参数。

 template <typename T>
 Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM