noexceptがついてないファイルシステム操作

C++17のファイルシステムライブラリは、エラー時に例外を投げるバージョンと、error_codeへの参照をパラメータにとって例外を投げないバージョンの2つが用意されています。

ですが後者についても一部、例外を投げる可能性がある関数があります。 戻り値でpathオブジェクトが返る関数にnoexceptが付いていないのですが、それはreturn時にメモリ確保に失敗したことによって例外が起こりえます。

そういう関数にはnoexceptが付いていません。

参照

Boost 1.69.0がリリースされました

Boost 1.69.0がリリースされました。リリースノートはいつものように、日本語訳 + 情報補完したものをboostjpサイトで公開しています。

今回、新ライブラリとして安全な整数演算をするためのライブラリSafe numericsが入りました。

また、ライブラリをビルドするときに、Boost.Buildではデフォルトでvisibilityがhiddenになります。

Boost.Systemがヘッダオンリーになって使いやすくなっています。

その他、リリースノートを参照してください。

C++の勉強会を新しく企画しました

cppmix.connpass.com

C++ MIX」という名前で、新しい勉強会を @okdshin さんと企画しました。

休日に勉強会開催をするのはパワーがすごく必要でたいへんなので、いまのところ継続性を重視して平日夜に2時間程度の開催ということにしています。

Boost.勉強会は、勉強会の名前でBoostネタにしばられてしまう、ということが長い間指摘されていたこともあり、今回Boost.勉強会がもともと意図していた「C++周辺の勉強会」であることがわかる名前にしてあります。

cpprefjp : <filesystem>のリファレンス作成が完了しました

2017年11月から作業していたので、10ヶ月もかかってしまいました。 引き続き、C++17のライブラリと言語仕様のメジャーな機能を優先的に作業し、C++20も合間を見て作業していきます。

Boostの創始者Beman Dawes氏が引退

1998年5月にBeman氏が提案したことからBoost C++ Librariesプロジェクトがはじまりました。そこから20年が経ったことを期に、Beman Dawes氏がBoostから引退されます。

彼が作成したFilesystem、Timer、Endianといったライブラリは、他者にメンテナンスが移譲されます。

C++界隈ではこれまでにも何人かの著名な方がC++から引退されています。

  • 『Effective C++』シリーズ著者のScott Meyers
  • Boost.MPL作者、『C++ Template Metaprogramming』著者のDave Abrahams (現在はApple社でSwift開発に携わっている)
  • 『Modern C++ Design』著者のAndrei Alexandrescu (現在はD言語の開発者)

Boost 1.68.0がリリースされました

Boost 1.68.0がリリースされました。

いつものように、リリースノートの日本語訳 + 情報補完したものを、boostjpサイトで公開しています。

文字列連結

char配列、charstd::stringの任意の組み合わせを連結する関数を書きました。メモリ確保を一回だけします。

C++17の畳み込み式で、全体の文字列長を計算しています。

#include <string>
#include <cstring>
#include <utility>

std::size_t string_length(const std::string& s) noexcept
{
    return s.size();
}

std::size_t string_length(const char* s) noexcept
{
    return std::strlen(s);
}

std::size_t string_length(char) noexcept
{
    return 1;
}

template <class... Strings>
std::string concat_string(Strings&&... strs)
{
    std::string result;
    std::size_t length = (string_length(strs) + ...);
    result.reserve(length);
    ((result += std::move(strs)), ...);

    return result;
}

#include <iostream>
int main()
{
    std::string result = concat_string("Hello", ' ', std::string("World"));
    std::cout << result << std::endl;
}

出力:

Hello World

Boost 1.67.0がリリースされました

Boost 1.67.0がリリースされました。リリースノートはいつものように、翻訳 + 情報補完したものをboostjpサイトで公開しています。

今回の新ライブラリは、契約プログラミングをサポートするContractと、高階関数を使いやすくするHOF (Higher-order functions) です。

今回のアップデートでは、メンテナンスが滞っていたDateTimeの多くのバグが修正されたり、Type Traitsに任意の式が有効か判断するメタ関数が入ったりしています。

Boost.Pythonで生成されるライブラリファイル名が変更されているので注意してください。

1引数コンストラクタ以外に対するexplicit指定

C++03では、ひとつの引数をとるコンストラクタで変換コンストラクタ以外に対してはexplicitを付ける、という慣習がありました (別の言い方をすると、パラメータ付き構築にexplicitを付ける)。

C++11では、波カッコ構文による「一様初期化 (Uniform Initialization)」と初期化子リストがあるので、少し事情が異なります。C++11では、explicitを付けたコンストラクタは、X x = {a, b, c};のような代入演算子を伴うリスト初期化が禁止されます。

struct X {
    X(int, int) {}
};

struct Y {
    explicit Y(int, int) {}
};

int main() {
    X x {1, 2}; // OK
    Y y {1, 2}; // OK

    X x2 = {1, 2}; // OK
//  Y y2 = {1, 2}; // error
}

そのため、1引数をとるコンストラクタにデフォルト引数をつけてデフォルトコンストラクタと実装をいっしょにすると、意図と違った挙動になる可能性があります。X x = {a, b, c};構文を許可するかも含めて、任意のコンストラクタにexplicitを付けるかどうかを検討しましょう。

struct A {
    A(int=0) {}
};

struct B {
    explicit B(int=0) {}
};

int main() {
    A a{}; // OK
    B b{}; // OK

    A a2 = {}; // OK
//  B b2 = {}; // error
}

例として、string(int pos, int len)みたいなコンストラクタは、explicitにしたほうがいいですね。