C++使用boost::lexical_cast类的方法

9

我想使用Test类配合boost::lexical_cast使用。我已经重载了operator<<operator>>,但是这给了我运行时错误。
以下是我的代码:

#include <iostream>
#include <boost/lexical_cast.hpp>
using namespace std;

class Test {
    int a, b;
public:
    Test() { }
    Test(const Test &test) {
        a = test.a;
        b = test.b;
    }
    ~Test() { }

    void print() {
        cout << "A = " << a << endl;
        cout << "B = " << b << endl;
    }

    friend istream& operator>> (istream &input, Test &test) {
        input >> test.a >> test.b;
        return input;
    }

    friend ostream& operator<< (ostream &output, const Test &test) {
        output << test.a << test.b;
        return output;
    }
};

int main() {
    try {
        Test test = boost::lexical_cast<Test>("10 2");
    } catch(std::exception &e) {
        cout << e.what() << endl;
    }
    return 0;
}

输出:

bad lexical cast: source type value could not be interpreted as target

顺便提一下,我正在使用Visual Studio 2010,但我已经尝试过Fedora 16并使用g++编译器,结果也是一样的!


有趣的问题,到目前为止还找不到真正的答案。看起来流出了问题:1. 因为当它进入流操作符时,只有 a 被更新,b 没有被更新。我添加了另一个字符串来检查空格是否被错误解释,但即使字符串也没有被更新。2. 当你退出操作符时,它会抛出异常,它检查了我不理解的东西然后决定抛出异常。 - Klaim
你应该使用默认构造函数、拷贝构造函数和析构函数的默认版本,而不是自己定义它们:编译器会为你生成它们(在拷贝构造函数的情况下,编译器会更正确地生成,详见此FAQ)。 - Luc Touraille
1个回答

8
你的问题在于boost::lexical_cast在输入时不会忽略空格(它会取消输入流中的skipws标志)。

解决方法是在提取运算符中手动设置标志,或跳过一个字符。确实,提取运算符应该与插入运算符相对应:由于你在输出Test实例时明确放置了一个空格,因此在提取实例时也应明确读取空格。

这个线程讨论了这个主题,推荐的解决方案如下:

friend std::istream& operator>>(std::istream &input, Test &test)
{
    input >> test.a;
    if((input.flags() & std::ios_base::skipws) == 0)
    {
        char whitespace;
        input >> whitespace;
    }
    return input >> test.b;
} 

+1:我刚刚在搜索了10分钟后才发现到底发生了什么... - Klaim
可以了,谢谢!但是他们为什么要这样做呢?我刚发现 boost::lexical_cast<int>(" 123") 也会抛出相同的异常! - Kia.celever
这个问题在Boost论坛上已经被广泛讨论过。在这方面,这个帖子非常有趣。这个线程值得一看。 - Luc Touraille

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接