Visual Studio 2013 の std::is_pod のバグ
Visual Studio 2013 Update 3 では以下のコードがコンパイルエラーになります。
#include <type_traits> static_assert(std::is_pod<int>::value == true, ""); static_assert(std::is_pod<int*>::value == true, ""); static_assert(std::is_pod<int&>::value == false, ""); // 1 static_assert(std::is_pod<int&&>::value == false, ""); // 2
1と2のアサートに失敗します。 参照型と右辺値参照型の is_pod が true になってしまいます。
C++の規格書を読む限り、参照型はPOD型ではないのでこれらはfalseになるのが正しい挙動のはずです。
他の処理系では
gccとclangでは上記のコードはエラーになりません。正しい結果です。
Boost.TypeTraitsでは
boost::is_podでは次のコードはエラーになりません。正しい結果です。
static_assert(boost::is_pod<int&>::value == false, ""); static_assert(boost::is_pod<int&&>::value == false, "");
std::is_podに関する他のバグ
std::is_podのバグ - とくにあぶなくないRiSKのブログ
まとめ
規格書と他の処理系の実装を見る限り、VisualStudio2013の挙動はバグではないかと思います。 ググっても参照のis_podに関して書いているところが見つからなかったので*1自信はありません・・・。
FizzBuzz(2)
FizzBuzz3つ目はboost::rangeを使って [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
FizzBuzz(1)
FizzBuzz2つ目はtemplateの特殊化を使って [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
早くもネタ切れの予感…
FizzBuzz(0)
今さら感満載ですが、FizzBuzz問題*1をC++で書いてみようと思います。 ただし違う方法で何通りかけるかを頑張ってやってみようと思います。 あらかじめググらずに、他の人とかぶっても気にしない方針で。
まずは普通にif文を使って、
さて何通りかけるでしょうか・・・ つづく
std::functionをシリアライズできなくてつらい
例えばウィンドウがリサイズされたときの処理を設定するとき、
Window window; window.on_resize() += [](int width, int height) { /* リサイズされたときの処理 */ };
のように書いて、Windowクラスのほうではstd::function(boost::function)で保持しようかと思っていました。 しかしそうするとWindowクラスをBoost.Serializationでシリアライズできなくなってしまいます。
フリー関数やラムダ関数をシリアライズするのは不可能なので*1、関数オブジェクトのインターフェースクラスを定義して、それを継承したクラスを用意するという、C++03時代の方法しかなさそうです。
つらい。
*1:少なくともポータブルな方法は無い
boost::file_system の directory_iterator は "." と ".." をとばす
boost::file_system::directory_iteratorを使うとディレクトリ内のファイルやディレクトリを簡単に列挙することができます。
#include <boost/filesystem.hpp> using namespace boost::filesystem; for (directory_iterator it(current_path()); it != directory_iterator(); ++it) { std::cout << it->path().filename() << std::endl; }
このとき、Win32APIのFindFirstFile/FindNextFileを使ったときとは違って、"."(カレントディレクトリ)と".."(親ディレクトリ)は列挙されません。Win32APIを使うときはこの2つのディレクトリを毎回チェックしてはじいていたので、列挙されないのは地味にうれしいです。