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

Template overload of insertion operator >> causing cin issue

所以我有一个项目,我将用户输入的数据插入 类。所以我重载了 >> 运算符。因为我有 类 结构相似,所以我把重载做成一个模板来尝试节省时间。使此模板重载 类 的朋友似乎可行,因为我没有遇到任何编译错误。

我的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;

}

main 中使用 cin >> foo 时出现问题 - 我收到警告标题 "more than one operator >> matches these operands"。陪同:

错误 C2593:'operator >>' 不明确

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

我的main.cpp:

// main.cpp

#include "ClassDefs.h"

int main(){

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

    return 0;
}

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

任何帮助或建议将不胜感激:)

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

它变得有点令人费解,但我想我会分享,以防其他人遇到使用模板重载运算符的问题。

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

//ClassDefs.h

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

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

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

//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
    }

现在我可以在 main.cpp 中将模板 userNewMeas() 与模板 >> 和模板 Exception 一起使用。目标可能对每个人来说都很难看到,但我试图为任何测量类型重载 >>,并且有一个异常 class 包含根据输入的测量抛出的不同错误消息。