2014年8月7日木曜日

VisualC++2013とClang3.4.2でソースコードを共通にする際に日本語を使う

参考にしたページ:

http://d.hatena.ne.jp/osyo-manga/20110406
http://blog.cppcms.com/post/105


確認環境

  • Windows7 x64 with SP1 日本語版
  • VisualStudio2013 update1 日本語版
  • Cygwin(2014/08/06時点での最新版をALL Install → clang3.4.2がついてきた)


やり方

BOMつきUTF-8ファイルにし、先頭に以下を入れる:

#if defined(_MSC_VER)
#pragma execution_character_set("utf-8")
#endif

それをコンソールに出力する場合、Windows環境では以下のようにする:

_setmode(::_fileno(stdout), _O_U16TEXT);
    // _O_U8TEXT にして printf を使うと実行時エラーになって落ちる。
auto len = strlen(text);
wchar_t converted[1024];
auto len2 = MultiByteToWideChar(CP_UTF8, 0, text, len, converted, 1024);
if(len2 != 0)
{
    converted[len2] = 0;
    wprintf(converted);
}

その他

Linuxでビルドしたclangも同じ動作かどうかは未確認。
VisualStudio2012はpragma execution_character_setが使えない(update4でも)。VisualStudio2010はOKらしい。

2014年4月10日木曜日

MSVC11で、指定型について特定のシグニチャを持つメンバ関数があるかどうか調べるメタ関数を実装した

BOOST_TTI_HAS_MEMBER_FUNCTION使え(ぉ

派生が絡むとちょっと面倒くさかった。結果として以下の様な感じに。

template <typename T>
struct has_xxx
{
private:
    typedef char yes_t;
    typedef double no_t;

    template <typename F, F> struct Sfinae;
    template <typename U, void (U::*P)() const>
    struct Sfinae<void (U::*)() const, P> {};

    template <typename U> static yes_t check(Sfinae<decltype(&U::xxx), &U::xxx>*);
    template <typename U> static no_t check(...);

public:
    static bool const value = sizeof(yes_t) == sizeof(check<T>(0));
};

Sfinaeの特殊化でシグニチャを調整すればOK。この実装ならxxxが親クラス側で実装されていても正しく判定できる。