C++

C++ の名前解決 ADL その2

C++

はじめに C++20 の前の基礎知識として、以前 C++ の名前解決 でも紹介した ADL (Argument-dependent name lookup) に関連した話題を少し紹介してみます ■蛇足ここで「名前を探す」などと言っているのはすべてコンパイル時の話です コンパイラ内部の話です 実…

C++ の名前解決

C++

はじめに 標準を読むと C++ の名前解決の決まりについて細かく規定されているのがわかると思いますが、ここではその詳細な検索の順番や個別規則の詳細などについては説明しませんここでは直観的でない2つの決まりについて説明します 一つは一般の名前解決で…

Hacker's Delight 5章にあるビットの数え方

C++

(前回の続き) 1ビット ビットが1つあるときにとりうるパターン(数値)は 0, 1 の2種類で、このとき立っているビットの数も 0個か 1個です 数値が 0 なら立っているビットの数も 0個 数値が 1 なら立っているビットの数も 1個これは考えるまでもありま…

C++ 数値操作と計算の練習

C++

はじめに 画像を拡大縮小するとき、グラフが表示範囲内に収まるようにするとき、カメラと注視点との距離を変えるとき、スライダの注目範囲を変えるときなどなどに、2倍 4倍 8倍であったり、10倍 100倍 1000倍であったりといった一定の規則で変化する数列が必…

C++ strict weak ordering

C++

はじめに 標準テンプレートライブラリの多くのアルゴリズムが strict weak ordering という規則に従った演算子を要求します strict weak ordering とは何でしょうか本来は数学の用語ですが、C++ の文脈での strict weak ordering というのは、当たり前の ope…

C++ 基底クラスのアクセス指定子と基底クラスを指すポインタへのキャスト

C++

「C++ 基底クラスのアクセス指定子」では、「基底クラスのアクセス指定子は、基底クラスの public メンバと protected メンバを派生クラスでどう扱うのかということを指定しているだけだ」と言いましたが、実はそれだけではなく他にも機能がありますそれは、…

C++ 11 ラムダ式とは何か

C++

はじめに C++ 11 で各種言語にある無名関数を C++ でも使うことができるようになりました この無名関数のための新たな仕組みをラムダ(lambda)、正確にはラムダ式(lambda expressions)といいますラムダ式は無名の関数オブジェクトを作るための構文で、そ…

C++ テンプレートクラスにあるテンプレートメンバ関数の特殊化

C++

はじめに 特殊化していないテンプレートクラスの中にある内側のテンプレートだけを特殊化するということはできません標準では次のように言っています 14 Templates 14.7 Template instantiation and specialization 14.7.3 Explicit specialization 18 In an…

C++ 11 rvalue とは何か

C++

はじめに これは気にする必要のないことなのでこれまで意図的に説明しなかったことなのですが、rvalue とは何者なのかということについて気になる人も多いようですrvalue参照についてはこれまで何度か説明をしてきましたが、そこでは「rvalue参照の rvalue …

C++ 11 コピーと move と戻り値の関係

C++

はじめに C++ 11 になり、オブジェクトの move ができるようになったことで関数の戻り値の型にクラスを指定しても問題ない程度の負荷で済む場合も多くなりましたが、クラスの宣言の仕方によってはその恩恵を得られない場合もあります ここでは関数の戻り値と…

Q.「rvalue参照自体はlvalue」ってどういうこと?

A.rvalue参照(変数に名前が付いていたらその変数)自体は(名前を持っているので名前を持っているものはその型が何だろうと)lvalue であるということです変数の型の宣言が何だろうととにかく名前の付いているものが lvalue で、名前の付いていないものが r…

Q.ちゃんと T&& を渡してるのになぜか T& の方が呼ばれるんだけどなんで?

void foo( cbar&& ); void foo( cbar& ); void baz( cbar&& bar ){ foo( bar ); // なぜか cbar& の方が呼ばれる } A. cbar&& の方を呼んでもらうためには std::move が必要です void baz( cbar&& bar ){ foo( std::move(bar)); // cbar&& の方が呼ばれる } …

C++ 11 の rvalueリファレンスと一時オブジェクト

C++

はじめに この見えないけれどもそこにある一時オブジェクト(temporary object)というものは C++ においては実行効率や安全性などの面でとても重要なものなのですが、見えないので疎かにされがちですしかし C++ 11 になり rvalue参照が追加されたことで一時…

C++ 11 auto の使い方

C++

はじめに C++ 11 で auto キーワードが型推論機能として生まれ変わりました 7 Declarations 7.1 Specifiers 7.1.6 Type specifiers 7.1.6.4 auto specifierここでは auto の4つの使い方について簡単に説明します auto, auto&, const auto&, auto&& (auto* …

C++ プリプロセッサメタプログラミングの基礎(続き)

C++

(前回の続き) マクロの再帰はエラー マクロの再帰はエラーになりますが、これはプリプロセスでエラーが出ているのではなく、プリプロセスで置換されずに残ったシンボルがコンパイルの段階で見つからないためにエラーになっているものです例えば下記のコー…

C++ プリプロセッサメタプログラミングの基礎

C++

置換の基本 関数形式のマクロに渡されたものはなんでもその通りに置換されます #define FOO( p ) p FOO( 1 ) ↓ //p → 1 1FOO( "aaa" ) ↓ //p → "aaa" "aaa"FOO( bbb ) ↓ //p → bbb bbb渡されたものがマクロであればさらにそれも置換されます #define FOO( p …

C++ 11 の rvalueリファレンスと swap

C++

今までの swap 今までの swap の実装は次のような感じでしょうか template<typename T> inline void swap( T& lhs, T& rhs ){ T temp = lhs; lhs = rhs; rhs = temp; } コピーが3回呼ばれます cfoo::cfoo( const cfoo& ) cfoo::operator=( const cfoo& ) cfoo::operator</typename>…

C++ 11 の rvalueリファレンスと reference collapsing

C++

rvalueリファレンス rvalueリファレンス自体については「C++ 11 の rvalueリファレンス」に譲ります reference collapsing C++ 11 からリファレンスのリファレンスが解禁されました &記号を3つも4つも書けるようになったというわけではありませんが、type…

C++ 11 の rvalueリファレンス

C++

はじめに C++ 11 の最大の変更は rvalue参照(rvalue reference)が追加されたことです rvalue参照とは何でしょうか まとめ 先に結論を言ってしまうと、rvalue参照というのは破壊可能な参照のことですなぜ破壊可能かというとそれは破壊可能なオブジェクトを…

C++ その文字列テーブルはもう古い

C++

その文字列テーブルは動的?静的? 今次のような文字列テーブルがあるとしましょうfoo.inl DEFINE_FOO( foo, "Foo", "あああ" ) DEFINE_FOO( bar, "Bar", "いいい" ) DEFINE_FOO( baz, "Baz", "ううう" ) DEFINE_FOO( qux, "Qux", "えええ" ) foo.h enum eFo…

C++ タイプセーフなエンディアン変換

C++

はじめに 今、次のようなエンディアン変換の関数と構造体があるとしましょう void swap_byte_order64( size_t celt, void* pelt ); void swap_byte_order32( size_t celt, void* pelt ); void swap_byte_order16( size_t celt, void* pelt ); typedef float …

C++ コンパイル時に値の型を知る方法

C++

C++03以前にはそんなものはない C++03以前には値の型を得ることのできるような仕組みは存在しませんそれでも事前に登録しておいた型だけで構わないという限定的な条件の下でなら、似たような機能を実現することもできます BOOST_TYPEOF boost には BOOST_TYP…

C++ SFINAE

C++

SFINAE とは SFINAE は、Substitution Failure Is Not An Error の略です これは、テンプレートの展開途中に文法違反になるような候補があったとしても、他の候補があるのであればその文法違反はエラーとせずに無視するという仕様ですと言っても何のことを言…

C++ の初期化

C++

はじめに 初期化に無頓着な人は C++ の初期化の挙動について知らないということが原因の一つのような気がします そこでここでは C++ の初期化について説明します デフォルトコンストラクタ デフォルトコンストラクタというのは、引数なしで呼ぶことのできる…

C++ クラス宣言から private, protected を追い出す方法

C++

対策前 実装を隠したいが、当たり前のことながらメンバを宣言しない訳にはいかないfoo.h class cfoo { // public を先に置きたくても前方参照なものは先にないといけない public: int get_value() const; voidset_value( int value ); cfoo(); ~cfoo(); priv…

C++ テンプレートクラスをカスタマイズ可能にする方法

C++

はじめに 簡単なテンプレートクラスを実装しながらテンプレートクラスの動作を使う側から指定できるようにする方法を学びましょうと言っても、テンプレートクラスをカスタマイズ可能にする方法というのは何か特別なものがあるわけではありませんカスタマイズ…

C++ new と null とコンストラクタ

C++

まとめ プロジェクトで例外を使うにしても使わないにしても例外構文が有効な状態でビルドする場合は operator new には必ず例外の有無を指定すること malloc 組み込み系のアプリケーションでは処理系のヒープ関連関数を使うということはありません 普通は自…

C++ テンプレート関数の呼び出し間違いをコンパイル時に検出する方法

C++

はじめに 今、次のようなテンプレート関数があるとしましょう このテンプレート関数には問題があります template<typename pointer_type_> inline void my_delete( pointer_type_& p ){ if( p ){ delete p; p = NULL; } } template<typename pointer_type_> inline void my_delete_array( pointer_type_& p ){</typename></typename>…

C++ NULLポインタ経由のメンバ関数呼び出し

C++

実際に試してみると死なない 実際に試したところでは特に死んだりはしないようです struct cfoo { void foo() const { printf( "foo\n" ); } }; static_cast<cfoo*>(0)->foo(); またこんな感じのも死なないようです struct cfoo { cfoo* find( const char* name ) c</cfoo*>…

C++ 配列の要素数を静的に取得する方法

C++

C では C では次のように実装します #define elementsof( a ) (sizeof((a))/sizeof((a)[0])) 通常はこれで構わないのですが、これだと間違ってポインタを渡してしまってもエラーになってくれたりはしません○できる int aaa[10]; int bbb[elementsof( aaa )];…