插入运算符的模板重载>>导致cin问题

时间:2017-05-11 04:13:56

标签: c++ templates operator-overloading operators friend

所以我有一个项目,我将用户输入的数据插入到类中。所以我重载了>>运算符。因为我有类似结构的类,所以我将重载作为模板来尝试节省时间。使这个模板重载一个类的朋友似乎工作,因为我没有编译错误。

我的ClassDefs.h:

// ClassDefs.h

using namespace std;

#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <tuple>
#include <map>
#include <typeinfo>

class measurement {

    //friends

    template<class measT>   //measT are other similar measurement classes
    friend istream & operator >> (istream&, measT&);


private:
    string words;

public:
    //constructors and things like that here

};

template<class measT>
istream& operator >> (istream& is, measT& meas) {

    //a series of checks to ensure user entry is valid

    //enter user entry into private data
    //e.g. 

    string line;
    getline(is,line);

    meas.words = line;

    return is;

}

cin >> foo中使用main时出现问题 - 我收到一条警告标题,说“多个运算符&gt;&gt;匹配这些操作数”。伴随着:

错误C2593:'运营商&gt;&gt;'含糊不清

这是有道理的,但我对重载的粗略理解是它们允许您使用该运算符使用不同的类型,并且编译器“理解”用于每种情况的定义。

我的main.cpp:

// main.cpp

#include "ClassDefs.h"

int main(){

    string entry;
    cin >> entry;
        ^^ error here

    return 0;
}

我环顾四周,看到涉及显式,内联,命名空间的事情(我的using namespace std;似乎狡猾),但我还没有看到有人使用这个模板重载安排并遇到这个问题。我正在使用Visual Studio 2015社区。

非常感谢任何帮助或建议:)

1 个答案:

答案 0 :(得分:0)

所以我在@ user4581301的帮助下部分地解决了这个问题 - 我真的需要保持>>重载模板,以便我可以将该参数用于其中的模板异常类。

这有点令人费解,但我想我会分享以防其他人因使用模板重载运营商而遇到的问题。

首先,我将measurement从抽象基类更改为基类(以便它可以用作模板参数)并将内部的友元声明更改为:

//ClassDefs.h

template <class measT>  
friend istream& operator >> (istream&, measurement&);

其中measT是涉及的测量类型,用作异常类的参数。

然后在头文件中,>>重载了定义:

//ClassDefs.h

template<class measT>
istream& operator >> (istream& is, measurement& meas) {

//take user input
//do checks on it, throw Exception<measT> depending on which set of 
  exceptions are relevant
}

最重要的是,我不确定如何使用带有模板参数的运算符,但事实证明您可以明确地执行此操作:

//ClassDefs.h

template<class measT>
measT userNewMeas() {    //function to take user input and make into a type 
                         // of measurement

    try    { ::operator>><measT> (cin,newMeas); }
    catch  (Exception<measT>& error) {
        cout << error << endl;    // this output depends on which exception 
                                  // was called
    }

现在我可以在userNewMeas()中使用模板main.cpp和模板>>以及模板Exception。目标可能很难为所有人看到,但我试图为任何测量类型重载>>,并且有一个包含不同错误消息的Exception类,这取决于输入的测量值。