mogmo .NET

C#/XAML/VB6たまにC++についてメモ程度に書いていく。あくまで自分用。責任は取れません。

std::filesystemのcreate_directories関数を使おうとしたらはまった

std::filesystems::create_directories()を下のコードのようにして書いたら,Debug版では複数ディレクトリの作成に成功するが,Release版では作成できなくなるという現象に出会った。

bool CreateDirectories()
{
    CString path = _T("C:\\DummyDir\\DummySubDir\\Test");
    return std::filesystem::create_directories((LPCTSTR)path); // 成功した場合trueを返す
}

現象

返り値はtrueなのにフォルダが生成できていない現象が起きてしまいす。何度やっても結果は同じ...

自分なりの原因究明

知人と話し合い予想した原因を記しておく。

このstd::filesystem::create_directories関数オーバーロード関数となっていて,この時使っていたのは引数がひとつしかないstd::filesystem::create_directories(std::filesystem::path path)です。
受け付ける引数の型がstd::filesystem::path型なのに対し,(LPCTSTR)pathという形で入力していたため,std::filesystem::pathのコンストラクタで例外が発生してしまったことが原因?で今回のような現象が発生したと思われる...

cpprefjp.github.io


でもその考察だと,次の章で試した3,4番の方法は失敗するはずなのでは?と思った私。。。
うーん。わからん。

正しく言語化できているか自信ないのと,本当に原因がこれなのか自信がない。

とりあえずの解決方法

5の方法が確実と判断する。

bool CreateDirectories()
{
    CString path = _T("C:\\DummyDir\\DummySubDir\\Test");
    // 1: failed: これだとできない
    //return std::filesystem::create_directories((LPCTSTR)path);

    // 2: pass: path型に変換してから引数に入力すると問題なくフォルダが生成された。
    std::filesystem::path path1(path.GetString());
    return std::filesystem::create_directories(path1);

    // 3: pass: なぜかこれは成功する
    std::filesystem::path path2(path.GetString());
    bool result3 = std::filesystem::create_directories(path2);
    return result3;
    
    // 4: pass: なぜかこれも成功する
    std::error_code errCode;
    return std::filesystem::create_directories((LPCTSTR)path, errCode);

    // 5: pass: これが一番安全
    std::filesystem::path path5(path.GetString());
    std::error_code errCode5;
    bool result5 = std::filesystem::create_directories(path5, errCode5);
    return result5;
}

さいごに

その解釈間違ってますって場合はコメントやTwitterでDMくださいm(_ _)m

written by @mogmo1012