Rokiのチラ裏

学生による学習のログ

気になる内容メモ about C++1z #5

他の作業をしながらエントリを書いているためケアレスミスがあったらも〜しわけない。

__has_include for C++17

Feature-testing preprocessor predicates for C++17

ヘッダーファイルが存在する場合インクルードする__has_includeプリプロセッサ機能。

#if __has_include(<iostream>)
#include<iostream>
#endif

int main(){std::cout<<"iostream Power!"<<std::endl;}

GCCではver 5.0以降でならサポートしている。

Filesystem Library


Boost Filesystem Libraryをベースにしたファイル操作を扱えるFilesystemライブラリが導入されるとのこと。コードを書いた方が直接的でわかり易い。

$ cat test.cpp
#if __has_include(<filesystem>)
#include<filesystem>
#define NAIYO true
#endif
#define NAIYO false

int main()
{
    static_assert(NAIYO); // In GCC6.1.0 will say assert

    std::filesystem::path p0("~/Documents/cpp/"),p1("a.txt"),to("~/Documents/cpp/b.txt");
    std::filesystem::path from(p0/p1); // operator/によるp0とp1のファイルパス連結
    
    std::filesystem::path a(p0);
    std::filesystem::path a+=p1; // operator+=によるファイルパスの連結

    std::filesystem::path b(p0);
    b.concat(p1); // concatメンバ関数によるファイルパスの連結
    
    try{
        std::filesystem::copy_file(from,to); //ファイルをfromからtoにコピー
    }catch(std::filesystem::filesystem_error& er){ //エラーが発生した場合std::filesystem::filesystem_errorに例外が送られる
        std::cout<<er.what()<<std::endl;
        throw;
    }

    std::error_code error;
    std::filesystem::copy_file(from,to,error); //3rd argumentsにstd::error_codeオブジェクトの参照を渡す事によって例外送出の代わりにstd::error_codeオブジェクトにエラー情報を格納する事ができる
    if(error)std::cout<<error.message()<<std::endl; //エラーメッセージ出力
}
$ g++ -std=c++1z test.cpp
test.cpp: 関数 ‘int main()’ 内:
test.cpp:9:2: エラー: static assertion failed
  static_assert(NAIYO); // In GCC6.1.0 will say assert
(略)

また、std::filesystem::pathなどで指定の文字エンコーディングでファイルパス文字列を取得する事ができたりするとのこと。...手持ちのコンパイラが未実装なので確認できないのがなんかモヤモヤする。

Minimal incomplete type support for standard containers, revision 4

Minimal incomplete type support for standard containers, revision 4

不完全型をコンテナの要素に指定できるようになる内容の文面案。

Based on the discussion on the Issaquah meeting, we achieved the consensus to processed with the approach – “Containers of Incomplete Types”, but limit the scope to std::vector, std::list, and std::forward_list, as the first step. The approach itself is well-known shortly after the C++98 standard being shipped[1], is one of the main features provided by Boost.Container[2] and libstdc++, and is receiving increasing interests in libc++. By limiting the scope, MSVC STL, libstdc++, and libc++ already support the proposed solution.
#include<vector>
#include<list>
#include<forward_list>

struct A{
    std::vector<A> a;
    std::list<A> b;
    std::forward_list<A> c;
};

int main()
{
    A().a.push_back(1); // ill-formed.要素型が完全型になっていなければならない。
}

因みにBoost Container Libraryでは1.61.0現在、static_vectorとbasic_string以外の全てのコンテナに不完全型のサポートが入っているとのこと。

Wording for Constexpr Lambda

P0170R1 Wording for Constexpr Lambda

ラムダ式をconstexprとして定義、実行できるようになる。またキャプチャする変数の初期化がリテラルであった場合ラムダ式内で使用でき、またクロージャーオブジェクトがリテラル型ならば式内で評価する事ができる。

#include<functional>

int main()
{
    constexpr bool a(true);
    std::function<bool()> w([&a]constexpr{return a;});
    static_assert(w());

    unsigned int b(0); // constexpr指定子を付与していないがリテラル型での初期化のためキャプチャできる。
    std::function<unsigned int()> x([&b]constexpr{return b;});
    static_assert(!x());
}

GCC6.1.0ではNo Availableである。