7

サンプルコードは次のとおりです。

#include <iostream>
#include <stdexcept>
#include <cstring>
#include <ctime>
#include <sstream>

using std::cout;
using std::endl;

std::size_t const BUF_SIZE(1000);

std::ostream& operator<<(std::ostream& os, std::tm const& rhs)
{   
    os << asctime(&rhs);
    return os; 
}   

std::istream& operator>>(std::istream& is, std::tm& rhs)
{   
    while (is.peek() == ' ' || is.peek() == '\t')
    {   
        is.get();
    }   
    std::streampos curPos = is.tellg();
    char buf[BUF_SIZE];
    is.getline(buf, BUF_SIZE);
    char* ptr = strptime(buf, "%D %T", &rhs);
    if (ptr == 0)
    {   
        throw std::runtime_error("strptime() failed!");
    }   
    std::size_t processed = ptr - buf;
    is.seekg(curPos + static_cast<std::streampos>(processed));
    return is; 
}   

int main()
{   
    std::istringstream is("10101 07/09/12 07:30:00 123.24");
    int uuid(0);
    double price(0);
    std::tm ptime; std::memset(&ptime, 0, sizeof(tm));

    is >> uuid >> ptime >> price;
    cout << "UUID: " << uuid << endl;
    cout << "Time: " << ptime;
    cout << "Price: " << price << endl;
} 

ここで、struct tm! の << および >> 演算子をオーバーロードしようとしています。コードを g++ でコンパイルして実行すると、次のようになります。

UUID: 10101
Time: Sun Jul  9 07:30:00 2012
Price: 123.24

完全!

しかし、clang++ を使用してコンパイルすると、次のようになります。

UUID: 10101
Time: Sun Jul  9 07:30:00 2012
Price: 0

おっとっと!

何が起こっている?これはclangの問題ですか、それともistreamを処理している方法ですか?

4

1 に答える 1

9

私はこれを再現することができました (g++ 4.7.0 および libc++-svn を使用した clang++ 3.1)。簡単なデバッグ セッションでは、clang++ がeofbitafterを設定しgetline(これは正常です)、何らかの形seekgで set を引き起こすことが示されfailbitました。first clears eofbitシーク(§27.7.2.3/41)を考えると、これはバグのように聞こえます。

回避するには、と のis.clear()間の任意の場所に挿入します。getlineseekg

于 2012-06-12T03:21:32.983 に答える