関数テンプレートの引数のcv修飾を保持する

値渡しをすると引数のトップレベルのcv修飾は破棄されてしまいます。 そこでcv修飾を保持したければ、参照渡しで受けてやれば良いです。 参照渡しではconstを勝手に外すと関数内部でオリジナルの値が書き換えられてしまいかねないのでそのようなことは行われ…

user defined literalはグローバルスコープに定義出来る

今日までグローバルスコープにおけるアンダースコアから始まる名前は予約語なので、ユーザ定義リテラルはグローバルスコープで定義してはイケないと思っていたのですが、許容されるようです。 user defined literalが予約語の制約を無視できる理由 http://cp…

対数オーダーでTemplate Parameter Packから要素を取り出す

一巡先を見る為にライブラリ始めました。 怜-toki- C++ Template Meta Programming Library https://github.com/fimbul/toki ライブラリ自体に需要があるかは分かりませんが、基本的にプリプロセッサ無しで型コンテナやらメタ関数やらTMPやるときに役立ちそ…

渡された型のtemplate parametersを得るメタ関数2

先日の件を経てcv修飾に対応しました。 もっと賢い実装がありそうですが、constとvolatileならせいぜい2 * 2通りしかないので凝ったことせずにそのままSFINAEで対応。 #include <iostream> #include <typeinfo> #include <cxxabi.h> #include <type_traits> #include <boost/mpl/vector.hpp> template<class... Types> struct Foo; template<class T> str</class></class...></boost/mpl/vector.hpp></type_traits></cxxabi.h></typeinfo></iostream>…

std::is_sameとmpl::equal

結論 Twitterで何人かの方に教えていただきました。 typeidがトップレベルのcv修飾や参照を無視するので、それをデマングルするとその部分だけが違う型は同じように表示されていました。 template<template<class...> class Type, class... Args> static const boost::mpl::vect</template<class...>…

渡された型のtemplate parametersを得るメタ関数

以前から渡された型のtemplate parametersを得るメタ関数が欲しいなと思っていて気が乗ったので書きました。 結果はその後扱いやすいようにboost::mpl::vectorにして返す事にしました。 tp_type<Type>::typeであればboost::mpl::vector<Type>を tp_type<Type<Types...>>::typeであればbo</type<types...></type></type>…

TMPの条件分岐に条件演算子が使えても良い気がする

以下のコードはgccでインスタンス化が無限再帰するコードです。 ちなみにclangでは無限再帰しないのではなく、エラーメッセージすら表示出来ずにPLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:を表示してクラッシュします。(まだバグ報告はしていま…

コンパイル時/実行時両用アサートについて考える

SPROUT_ASSERTは非常に優れており、コンパイル時、実行時両方で使えます。 しかし、以下のようなコードはコンパイルエラーにはならず、実行時に初めてアサーションに失敗します。 constexpr auto i = 0; SPROUT_ASSERT(i == 1); 一方、static_assertを用いる…

ラムダよくわからない

ラムダの挙動は難しいです。 コピーキャプチャされた要素の型に関してはdecltypeを用いた具体例による説明が規格内にありました。 void f3() { float x, &r = x; // x and r are not captured (appearance in a decltype operand is not an odr-use) [=] { d…

C++でクロージャを作る2

コピーなどにコストがかかってパフォーマンスも然程良くないので使い道が微妙ですが、クラスもどきです。 こういうのはやはり参照で寿命管理が上手く扱える、ガベージコレクタありきの技術ですね、基本的にC++には向かないです。 メンバ変数の宣言と初期化は…

clangにbug reportを出した

Bug 16907 - Crash in lambda expression http://llvm.org/bugs/show_bug.cgi?id=16907 C++でクロージャを作る(先程加筆修正しました) のコードを書いている時に、clangがクラッシュするコードを見つけたので本日報告しました。 以下のコードを実行するとcla…

C++でクロージャを作る

C++でもJavascriptなどと同様にクロージャを作る事が出来ます。 環境(状態)を持った関数オブジェクトといった感じで、分かっている人にとってはなんてことはないと思います。 ポイントはlambdaをコピーキャプチャとした上でmutableにすることです。 構造体や…

コンパイル時に配列の任意の箇所へ要素を挿入する

コンパイル時に配列の任意の箇所へ要素を挿入し、その結果を新しい配列として返す関数です。 push_at(array, value, position); によってarrayの中のpositionにvalueを挿入した配列を返します。 同様のテクニックを用いて、配列のある位置に別の配列の要素を…

コンパイル時に文字列を結合する

コンパイル時に使える文字列型のようなものを用意します。 2つの文字列を受け取る際に、templateでその文字列長を推論して得られるようにしておき、あとはindex_tuple idiomを用いて結合処理をして新しい文字列型を返します。 このようにすれば、副作用を用…

コンパイル時toupperとtolower

見たまんまですね。 文字列リテラル又はsprout::stringから処理を施したsprout::stringを生成します。 C++1yならdecltypeの部分は無くても動きますが、C++11対応のため。 #include <type_traits> #include <sprout/string.hpp> #include <sprout/index_tuple.hpp> template<class T, std::size_t size, sprout::index_t... indexes> constexpr auto toupper_impl(const T (&str</class></sprout/index_tuple.hpp></sprout/string.hpp></type_traits>…

bug reportのその後

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58091 However current ICC agrees with GCC. We may have something in Bugzilla. Generally speaking, this is a basic C++ issue, doesn't have to do with the recent constexpr, and normally icc is very…

gccにbug reportを出した

先日の以下の要素の参照は曖昧かについて、Twitterで江添さんからおそらくgccのバグではないかとの意見を頂いた(参考記事 : おそらくgccのバグ)のでgccにbug reportを出しておきました。 記事の解釈が正しければ、暫くしたらgccでも参照出来るように修正され…

Boost.PPでFizzBuzzし、コンパイル時に逆FizzBuzzで結果を検証する

Twitterで話題にしたので実装しました。 プリプロセッサでFizzBuzzの実装に結構苦労しましたがslotを駆使してなんとかなりました。 プリプロセッサでの再帰をslot(変数として働く)の利用と自分自身のincludeを使うことで実現しています。 #ifndef INIT #defi…

以下の要素の参照は曖昧か

#include <type_traits> namespace test { template<int... args> struct test { static constexpr auto value = 1; }; } int main() { using namespace test; static_assert(test<1>::value == 1, ""); // test<1>::valueはambiguous? } あるnamespace内に同名のtemplate structが存在</int...></type_traits>…

コンパイル時 逆fizzbuzz [C++]

巷で噂の逆fizzbuzz問題です。 http://d.hatena.ne.jp/matarillo/20120515/p1 コンパイル時に解けるようにテンプレート引数として<fizz,buzz,fizz,fizz...>といった物を与えるとfizzbuzzにおいてそれを生成する最小の数列を要素として持つsprout::array型のオブジェクトを得るメタ関</fizz,buzz,fizz,fizz...>…

Cプリプロセッサの挙動の違い

Cプリプロセッサというのはgcc, clang, MSVCなどの処理系ごとに微妙に異なります。 #pragmaディレクティブなどは、各コンパイラ等の独自拡張機能をサポートする為などに使われていますが、Cプリプロセッサの差というのはサポートする機能の有無やキーワード…

boost mpl から fusion へ変換する

mpl::vector< T... > に列挙された型を要素とするfusion::vector< T... >を作る方法が思いつかなくて頭を抱えている— Fadis (@fadis_) July 29, 2013 こんな感じですかね。 #include <type_traits> #include <boost/fusion/container/vector.hpp> #include <boost/mpl/list.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/deque.hpp> #include </boost/mpl/deque.hpp></boost/mpl/vector.hpp></boost/mpl/list.hpp></boost/fusion/container/vector.hpp></type_traits>

ユーザ定義リテラルからpairを作る

ユーザ定義リテラルはその制約のキツさから全然融通が効かないので、あんまり遊べる要素とか面白い利用法とかが見つからないのですが、少し変わった利用が出来ないか考えてみました。 #include <type_traits> namespace ct { static constexpr std::size_t period = stati</type_traits>…

文字列リテラルから型文字列を作る1

これまで数多くの人が型文字列の生成において<'h','e','l','l','o'>などの入力で深い悲しみを感じて来ました。 C++11で生まれたユーザ定義リテラルは、数値からであれば型文字列を生成出来ますが文字列リテラルには適用できません。 以前プリプロセッサで実…

条件演算子の戻り値にはthrow-expressionを書くことが出来る

5.16 Conditional operator If either the second or the third operand has type void, then the lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the second and third operands, …

Template Meta Programming 1

標準ライブラリのtype_traitsにあるis_sameを自分で実装してみましょう。 恐らく最も簡単なメタ関数の1つです。 integral_constant、true_type、false_typeも標準ライブラリ通りに準備します。 is_sameでは与えられた2つの型が同じであった場合の特殊化を行…

index_tuple idiom

勉強会のスライドなんかでこの名前で見かけます。 非常によく知られたidiomですが、メモ程度に簡単にまとめ直します。 index_tuple idiomはindex_tuple<0,1,2,3,4>のように連番の整数値を型リストとして持つオブジェクト(index_tuple)を生成する為のidiomで…

C++11 スマートポインタの話

C++にはガーベジコレクタが言語的には存在しないので、動的に確保したオブジェクトのメモリの管理はプログラマが責任を持って管理しなければ、メモリリーク・リソースリークなどの問題を生じてしまいます。 今時のプログラマはこうした問題を引き起こすリス…

Qt FrameworkのGUIアプリケーションをMBPのRetinaディスプレイに対応させる

Qtで記述したアプリケーションを標準の設定でビルドするとRetina対応しておらず、ウィンドウやフォントにジャギーが生じてせっかくの美しいディスプレイも虚しく描画が汚くなる。 Retinaディスプレイに対応した美しい描画を行う為にはプロジェクト(.pro)ファ…

Mac OS X Lionにqtruby4(qtbindings) gemを導入する

rubyでもQtでGUIが書きたい それを可能にするのがqtruby4です gccとかqtとかは全部homebrewで入れてありバージョンは qt-4.8.2 gcc-4.7.1 です cmakeが必要なので brew install cmake c++-4.7を使うようにしておきます sudo ln -sf /usr/local/bin/c++-4.7 /…