読者です 読者をやめる 読者になる 読者になる

コンマ

ふと不思議に思ったものがあった。
線形代数ライブラリEigenの行列、ベクトルの初期化方法だ。

Eigen::Vector3d v;
v << 1.0, 2.0, 3.0;
v;  //  (1, 2, 3)

なんだか妙なことをしている。
どのようなしくみになっているのかを確かめるために実装を調べた。

どうやら コンマ演算子オーバーロードしているようだ。
はじめに <<演算子 で CommaInitializer なる中間オブジェクトを生成し、CommaInitializer の コンマ演算子オーバーロード で値を格納しているらしい。

恥ずかしながら今まで コンマ演算子オーバーロード可能であることを知らなかった。
そういえば、オーバーロード可能演算子に含まれている。

まあせっかくなので少し遊んでみたい。

#include <iostream>
using namespace std;

namespace hoge {
    template <typename Value>
    ostream& operator,(ostream& stream, Value value) {
        return stream << ',' << value;
    }
}

int main() {
    cout << 1,2,3,4,5;   // 1
    cout << endl;
    using namespace hoge;
    cout << 1,2,3,4,5;   // 1,2,3,4,5
    cout << endl;
}

出力

1
1,2,3,4,5

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

さて、この記事を書いている途中、コンマ演算子オーバーロード用いた Boost.Assign なるものがあることを教えていただいた。

#include <boost/assign.hpp>

int main() {
    using namespace boost::assign;
    std::vector<int> v;

    v += 1,2,3,4,5; // [1,2,3,4,5]
}

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
内部は、Eigen のそれと似たようなものなのだろう。
Boost.Assign ではこれ以外にも演算子オーバーロードされているようだ。