Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类上的二进制运算符重载_C++_Templates_Operators_Operator Overloading - Fatal编程技术网

C++ 模板类上的二进制运算符重载

C++ 模板类上的二进制运算符重载,c++,templates,operators,operator-overloading,C++,Templates,Operators,Operator Overloading,我最近试图评估我的操作符重载/模板能力,作为一个小测试,我创建了下面的容器类。虽然此代码在MSVC 2008下编译良好并正常工作(显示11),但MinGW/GCC和Comeau都在操作符+过载时阻塞。因为我更信任他们而不是MSVC,所以我试图找出我做错了什么 代码如下: #include <iostream> using namespace std; template <typename T> class Container { friend Contai

我最近试图评估我的操作符重载/模板能力,作为一个小测试,我创建了下面的容器类。虽然此代码在MSVC 2008下编译良好并正常工作(显示11),但MinGW/GCC和Comeau都在
操作符+
过载时阻塞。因为我更信任他们而不是MSVC,所以我试图找出我做错了什么

代码如下:

#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;
}
#包括
使用名称空间std;
模板
类容器
{
friend集装箱运营商+(集装箱和lhs、集装箱和rhs);
公共:无效setobj(T ob);
T getobj();
私人:T obj ;;
};
模板
空容器::setobj(T ob)
{
obj=ob;
}
模板
T容器::getobj()
{
返回obj;
}
模板
集装箱操作员+(集装箱和左舷、集装箱和右舷)
{
容器温度;
温度obj=lhs.obj+rhs.obj;
返回温度;
}
int main()
{    
容器a、b;
a、 setobj(5);
b、 setobj(6);
容器c=a+b;

cout我找到了解决方案,谢谢。基本上,在类中使用“friend”之前,你需要有一个函数原型,但是为了正确定义函数原型,你还需要声明类。因此,解决方案是有两个原型定义(函数和类)在顶部。以下代码在所有三个编译器下编译:

#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;
}
#包括
使用名称空间std;
//在下面添加了行
模板类容器;
模板集装箱操作员+(集装箱和lhs、集装箱和rhs);
模板
类容器
{
friend集装箱运营商+(集装箱和lhs、集装箱和rhs);
公共:无效setobj(T ob);
T getobj();
私人:T obj ;;
};
模板
空容器::setobj(T ob)
{
obj=ob;
}
模板
T容器::getobj()
{
返回obj;
}
模板
集装箱操作员+(集装箱和左舷、集装箱和右舷)
{
容器温度;
温度obj=lhs.obj+rhs.obj;
返回温度;
}
int main()
{    
容器a、b;
a、 setobj(5);
b、 setobj(6);
容器c=a+b;

cout“operator+”不是成员函数,也不是模板化的。它只是采用模板化参数的operator+。”

 template <typename T>
 Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
模板
集装箱操作员+(集装箱和左舷、集装箱和右舷)

我在GCC下尝试了一下,并对它进行了编译和运行,只做了一些更改。为了让GCC满意,我必须做两个更改

一个是friend template函数的声明。它是自己的模板声明,独立于类1,因此我使用U而不是容器类。我还去掉了运算符+之后的。我认为除非您编写模板专用化,否则您不需要这些

      template<typename U>
      friend Container<U> operator+ (Container<U>& lhs, Container<U>& rhs);
模板
friend集装箱运营商+(集装箱和lhs、集装箱和rhs);
第二,排队

Container<int>& c = a + b;
容器&c=a+b;
没有使用GCC,因为您要求存储对临时(添加结果)的引用。我删除了符号AND,以便有一个存储结果的位置


我刚才看到了你的帖子,这也是因为转发声明的缘故。我想我还是把它作为一个不需要它们的替代方案发布吧。当然,我只在GCC中测试过…

你最好直接在类中定义函数。另外,你应该将参数作为
const
引用传递

template <typename T>
class Container
{
public:
    friend Container operator+ (Container const & lhs, Container const & rhs)
    {
        // ...
    }
};
模板
类容器
{
公众:
friend Container operator+(集装箱常数和左侧、集装箱常数和右侧)
{
// ...
}
};

我认为运算符+是一个模板函数,不是吗?一个容器和一个容器将是两种不同的类型,因此编译器需要生成两个不同的运算符+函数来处理它们。这不是意味着运算符+是一个模板函数吗?它是一个函数模板。但是您省略了“”是正确的从模板的定义来看。(“”仅在指定要调用的函数模板时使用,并且仅当存在同名的非模板函数时才需要使用。)我在另一篇在线帖子中发现了这一点,这将是我个人对这两个函数的偏好(更简洁)。此操作将授予对所有模板专用项的访问权限(因此操作员+可以访问容器的专用项)。询问者的代码只希望授予操作员+的访问权限(只有操作员+可以访问容器的专用项)@litb:我也看到了提到的那个问题,但我在设置这样一个场景时遇到了麻烦。你能提供一个例子代码片段,其中int重载访问浮点的私有成员吗?@GRB,你总是可以人为地构造这样的情况。这在你的代码中是否真实发生并不成问题。仅仅是可能性当它发生(偶然)时,不会有错误消息,这足以让它排除它。像“const”、“private”和“friend”这样的概念就是记录依赖关系,同时尽可能地隐藏和松散。我知道代码可能不会导致这种情况发生,我遇到的问题是创建这样一个人工案例。我个人想不出一个,所以我想知道你是否可以。
      template<typename U>
      friend Container<U> operator+ (Container<U>& lhs, Container<U>& rhs);
Container<int>& c = a + b;
template <typename T>
class Container
{
public:
    friend Container operator+ (Container const & lhs, Container const & rhs)
    {
        // ...
    }
};