myoukakuのブログ

C++でゲームエンジンを作っていきます。

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になるのが正しい挙動のはずです。

他の処理系では

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

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自信はありません・・・。

*1:sscrisk (id:RiSK)さんが書いているのに類する情報はあった

ゲームエンジン製作方針

ゲームエンジンを趣味で作っているのですが、ただゲームエンジンだけを作っているとどういう機能が必要なのかわかりにくいので、ゲームを作りながら、必要だと思った機能をエンジンに追加していく、という方法で進めていこうかと思います。

に対応したいので、それらを作りながらということになります。

いつ形になるかわかりませんが、まあ趣味でやっているのでゆっくりと…

FizzBuzz(0)

今さら感満載ですが、FizzBuzz問題*1C++で書いてみようと思います。 ただし違う方法で何通りかけるかを頑張ってやってみようと思います。 あらかじめググらずに、他の人とかぶっても気にしない方針で。

まずは普通にif文を使って、

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

さて何通りかけるでしょうか・・・ つづく

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つのディレクトリを毎回チェックしてはじいていたので、列挙されないのは地味にうれしいです。