にゃははー

はへらー

1.52からboost::result_ofがコンパイルエラーになるかもしれない

1.51以前のboost::result_ofを使用しているコードでC++11モードをenableにしている場合、1.52に更新するとコンパイラによってはコンパイルエラーになるかもしれない。
というのもboost::result_ofはBoost 1.52から挙動が変わり、従来TR1式のresult_ofであったがN3276式decltypeが利用できる場合decltypeベースのresult_ofを使用するようになったからだ。
とはいえdecltypeが利用できるという環境でコード書いているのであればstd::result_ofがあるので影響が出る人は少ないかもしれない、が無いとはいえない(後述)。

具体的なコードは以下の通り

#include <boost/utility/result_of.hpp>

struct F
{
	void operator(int);
};

int main()
{
	boost::result_of<F()>::type *p = 0;
}

TR1式のresult_ofはnullary callに対しては特別な挙動をし常にvoidを返していた。ところが1.52以降のdecltype-baed result_ofは実際に呼べるかをテストする。
上記テストの場合、functor Fをnullaryで呼ぶことは出来ないためtypeは定義されない

ここで注意して欲しいのはresult_of内部でエラーになるのでは無く、定義されないという点だ。
1.52からのboost::result_ofはdecltypeで実装されているならばN3436によるSFINAE-friendlyな実装を行なっている。
C++11で導入されたstd::result_ofはSFINAE-friendlyなresult_ofではなく、boost::result_ofを使うメリットは十分にある*1

今回のリリースによるresult_ofの変更は今後影響範囲が大きくなる可能性があることからspecial noteが出ている。
A Special Note for Boost 1.52.0 and Higher
とはいえ現状N3276式decltypeを実装してるのはclangのみである。

TR1式のresult_ofはもはや古い。nullaryに対してvoidが返ってくることを期待してコードを書いてはいけない。

*1:GCCC++17までのreasonableな提案をC++11として扱うのでGCC 4.8.0以降のstd::result_ofはSFINAE-friendlyである
[v3] "SFINAE-friendly" std::result_of