B Io  ·  01月01日

問題描述: 在testfn函數中,switch imbue的部分會被filestr.imbue(std::cout.getloc());觸發, 接下來理論上會cout, 接著LOG(我自己寫的輸出封裝函數), 但是cout後就離開switch, 觸發流刪除事件了,LOG沒有觸發。

如果先LOG再cout則沒問題, LOG和cout都會被輸出到console。 像這樣,提供出stream.imbue_event非常多的信息。

LOG  [enum std::ios_base::event] stream.imbue_event = 1At testfn         ,line 00219
imbue_event
erase_event

出事代碼 C++

#include <iostream>     //std::ios, std::cout, std::cerr, std::clog, std::left
#include <iomanip>
#include <fstream>      // ofstream
#include <locale>       // std::locale

#include <typeinfo>
#include <chrono>
#include <thread>
#include <ctime>
#include <sstream>

template <typename T>
void Log(const char* varName, T  var, int line, const char* functionName) {
    std::stringstream ss;
    ss << "[" << typeid(var).name() << "] " << varName << " = " << var;
    std::ios_base::fmtflags originalFlags = std::cout.flags();/*FORMAT FLAG*/\

        /*auto now = std::chrono::system_clock::now();*//*TIME*/\
        /*std::time_t timestamp = std::chrono::system_clock::to_time_t(now);*//*TIME*/\
        /* std::cout << "\nTime taken at Total : " << duration.count() / 1000.0 << " millisecond" << std::endl;*//*TIME*/
        std::cout.width(0);
        std::cout << std::setfill(' ') << std::left << "LOG  "\
        << std::setw(50) << ss.str()/*TYPE*//*VARIABLE*//*VALUE*/\
        << "At " << std::setw(15) << functionName /*FUNCTION*/\
        << std::dec << ",line " << std::setw(5) << std::setfill('0') << std::right << line /*LINE*/\
        /*<< "File: " << __FILE__ */   /*FILE*/\
        /*<< ", Thread ID: " << std::this_thread::get_id() << ", "*//*THREAD*/\
        << std::endl; \
        std::cout.flags(originalFlags);
}

//register_callback, imbue_event, erase_event
void testfn(std::ios::event ev, std::ios_base& stream, int index)
{
    switch (ev)
    {
    case stream.copyfmt_event:
        std::cout << "copyfmt_event\n"; break;
    case stream.imbue_event:
        std::cout << "imbue_event\n"; break;
        Log("stream.imbue_event", stream.imbue_event, 219, __FUNCTION__);

    case stream.erase_event:
        std::cout << "erase_event\n"; break;
    }
}

void funcPart6()
{
    /*register_callback*/std::cout << "//---//\n";

    std::ofstream filestr;
    filestr.register_callback(testfn, 0);/*imbue_event*//*erase_event*/
    filestr.imbue(std::cout.getloc());
    /*
    * 使用register_callback來設定事件 如 copyfmt_event imbue_event erase_event
    * filestr.register_callback(testfn, 0);
    *
    /*
    * 筆記:
    * 試圖複製或複製但是構造了一個 std::basic_ofstream 對象,該類的複製構造函數是被刪除的(deleted)。
    * 這是因為 std::basic_ofstream 對象通常代表一個文件流,而文件流的複製構造函數不是允許的,
    * 因為一個檔案流在複製時可能會引起一些不可預測的行為。在這種情況下,應該避免直接複製 std::basic_ofstream 物件。
    */
}

共有 2 則留言

std::cout << "imbue_event\n"; break;
Log("stream.imbue_event", stream.imbue_event, 219, __FUNCTION__);

break 要放到 Log 後面,不然跑不到 Log 那行

謝謝,原來問題這麼簡單。