C++ でテンプレートを使えば静的にポリモーフィックな Duck Typing というか,ある構文が有効であれば継承関係も何も無くても O.K. (専門用語で言えば,あるコンセプトのモデルを全て受け付ける)というコードを書くのは非常に簡単.ただし,一方で静的多相であること(コンパイル時決定であり,型の情報を引きずり倒さなければならない)が欠点となる状況も多い.動的多相が実現できない,コードの肥大化(code bloat)がある,など. #後日注釈 (2005/11/17):実装をヘッダに書かないといけないという制約も大きい. 一方で C++ において,継承関係のないクラス間で動的多相を行う手法がないかというとそういうことはない.これを実現する技法は自分が知っている範囲で2つ.どちらも個人的に「型消去 (Type Erasure)」と呼んでる(で,実際にそう呼ばれることがある)技法. 1つは
なんか,std::ifstream のバイナリモードでファイルの読むのが,すごくツライんですけど,気のせいだろうか。 #include <fstream> #include <iostream> #include <string> static const ::size_t BUFSIZE = 1024; int parse(const std::string& path) { std::ifstream f; try { char buf[BUFSIZE]; // open() のために例外設定 f.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit); f.open(path.c_str(), std::ios::in | std::ios::binary); // read() のために例外再設定 f.
c++ で template関数を使う場合に特殊化により関数を制作する時に、template関数が定義されているヘッダーを複数のソースに使う場合に同じ関数が二度生成されてしまいますが、これはどう解決すればよいですか? 例えば次のような場合です。 // header_temp.hpp template <typename T> void foo(T a) { cout << a << endl; } // source_1.cpp #include "header_temp.hpp" #include "header_class_alice.hpp" // class Aliceが定義されている void hoge() { foo<Alice>(10); } // source_2.cpp #include "header_temp.hpp" #include "header_class_a
STL はまあ普通に使う、くらいの軟弱な知識で C++ を使っていると、クラス内で関数テンプレートの特殊化をしようとしてコンパイルエラーになって、なんでここで特殊化できないんだよ〜と愚痴を言っていたら、さらに恐ろしいことに、特殊化はできないのに部分特殊化はできる場合に遭遇したりして、 C++ の闇に触れた気分になる。でも実はそうでもないという話(少なくとも、ユーザの側から理解するだけなら、ね)。 2025-02-16: この記事は C++03 時代に書かれたものですが、 C++23 でもここで解説している仕様に大きな変更はないはずです。 (部分)特殊化できる条件 ややこしく感じる理由は、特殊化できる条件と、部分特殊化できる条件が全く別だから。実はそんなに複雑ではない。 特殊化できる OK: 名前空間スコープで定義 NG: クラススコープで定義 部分特殊化できる OK: クラステンプレート
たいていのMPIライブラリには、伝統的にmpi{cc,f90,cxx}といったコンパイラのラッパーが付いています。-Iとか-Lとか-lを適当に設定したうえで、コンパイラを呼び出してくれる便利なものですが、 これが最終的に呼び出すコンパイラを切り替える方法がライブラリによってバラバラなので、ざっくりとまとめておきます。 IntelMPIの場合 コマンド名で呼び出すコンパイラを切り替えています。 mpicc: gcc or cc mpicxx: g++ mpifc: gfortran mpigcc: gcc mpigxx: g++ mpif77: g77 mpif90: gfortran mpiicc: icc mpiicpc: icpc mpiifort: ifort gccのかわりにgcc44とかを呼びだければPATHの設定で先にくるようにしておけば良いはず*1 mpich2, mpich
コンパイル時に処理を切り替えたい場合に使用。Strategyパターンでは継承により処理を切り替えるが、こちらはテンプレートパラメーターで処理を切り替える。以下のサンプルコードは上述のLINK先のStrategyパターンのをもじって書いた。複数の特徴(戦略)をクラスに持たせる場合はこちらのほうが継承を使ったものよりもメンテの手間がはぶけてよい(継承を使うと全ケースの組み合わせを継承を使って書かねばならないので大変) #include<string> #include<iostream> #include <vector> #include <algorithm> using namespace std; //ポリシークラスを呼ぶための箱 template<class Policy> class MaxSearchStrategy { public : void Execute(const v
はじめに 速いプログラムで得られるメリットを超えるようなコストを払わないように。 まずは動くプログラムを書いて目的を達成することが大事。 自分律速じゃなくてプログラム律速だなと感じた段階でリファクタリングを考える。 プログラム本来の意図が読み取れなくなりそうなマニアックな高速化は避ける。 清く正しくメンテナンスしやすいプログラムを書くほうが結局は生産的。 学習目的でない限り、車輪の再発明を避ける。 やろうとしていることはきっと既に誰かが実現し、 再利用可能な形で公開してくれているはず。 まずは標準ライブラリとかBoostを探してみる。 あとGitHubでスターが多いやつとか。 頑張れコンパイラ Intelの icc でビルドされたプログラムは速いらしい。 gcc や clang の最適化技術も着々と進歩しており、 新しいコンパイラを使うほうがその恩恵を受けられる。 最適化オプション htt
この記事はC++ Advent Calendar 2012の15日目にエントリしています。 内容はC++11「ムーブセマンティクス」の入門記事となっています。 もくじ ムーブセマンティクス再考 シンタックス vs. セマンティクス コピー vs. ムーブ ムーブのもつ2つの意味 C++11のムーブセマンティクス対応 auto_ptrからunique_ptrへ auto_ptrの暗い過去 unique_ptrへの移行 std::moveの役割 ムーブセマンティクスを使おう C++11標準ライブラリとムーブ ムーブ"後"の中身は? ムーブを利用して関数を書く (本文のみ約9500字) まえがき To move or not to move: that is the question. ― Bjarne Stroustrup, 2010(改)*1 プログラミング言語C++の新しい国際標準規格*2
C++11 では Template で不定個の引数をまとめて扱えるようになっています。 void func00( int a0, float a1, int a2 ) { } template void Exec00( A0... a0 ) { func00( a0... ); } void VT_Test() { Exec00( 1, 2.0f, 3 ); } 例えば上の例は VT_Test() からそのまま Exec00 経由で func00() を 呼び出しています。 func00() の引数の数が変わっても Tempalte の宣言を変える必要がなくなります。 今までこのようなケースでは、Template にマッチさせるために 引数の数だけオーバーロードか特殊化が必要でした。 template void Exec01( A0 a0 ) { func00( a0 ); } templ
社内勉強会、今期(と言ってももうあと1ヶ月もないですが)は、数理最適化勉強会と、Effective Modern C++輪読会をしています。この記事は、後者のEffective Modern C++輪読会で、『Effective Modern C++』5章の一部を輪読した時の資料を流用したものです。 C++11と言えば、昔のC++(03)から色々あって多くの機能が追加されとても便利になったバージョンです。さらに、C++14は11では間に合わなかった・忘れていた色々な便利なものを補填したもので、Effective Modern C++輪読会は、『Effective Modern C++』を教科書にしながらこのC++11/14について学ぶ会になっています。 時は既に2016年、gccもclangもMSVC++も概ねC++14が使えるようになっており、もはやC++14が使えないコンパイラにはC+
たまに出て、なんなんだろうなぁと思っていたこの警告。 foo.cpp:37: warning: 'Foo::bar' will be initialized after調べてみると メンバ変数 d と i の宣言順と、コンストラクタ初期化子での記述順が違うとでる警告です。 メンバ変数の宣言順とコンストラクタ初期化子の順番が違うと怒られる - みねこあ なるほどなるほど。宣言順に初期化されるからなのね。 手元の Effective C++ (第二版) の第13項によると、初期化リストの順とは関係なく宣言順にメンバ変数が初期化される理由は、 「デストラクタはコンストラクタとは逆の順番に呼び出されなければならない」 というルールがあるからだそうです。 例えば、二種類のコンストラクタを定義し、その初期化リストの順序が違う場合。 初期化リスト順に変数を初期化すると、オブジェクトごとにどちらのコンスト
こんにちは。 最近勉強し始めたc#でWPFをやってみましたが、もう見たくもありません。 さて、今日はc++を使っていても意外になかなか覚えない、コンストラクタの暗黙の宣言 / 非宣言をまとめておきたいと思います。 関連して、よく問題になる暗黙のコピー、ムーブの問題についても書き留めておこうと考えています。 コンパイラが用意してくれる特殊関数は以下になります。(c++14時点) デフォルトコンストラクタ コピーコンストラクタ コピー代入演算子 ムーブコンストラクタ ムーブ代入演算子 デストラクタ 何事もなければこれらが全て暗黙的に宣言・定義されます。( class something {}; ) 平和ですね。みんながみんなこうであればよいのですが、そうはいかないのです。 #コンストラクタが暗黙に宣言されるとき、されないとき ざっくり以下に表にまとめました。 なお、constructorをct
通常,C++のテンプレート関数(orクラス)をライブラリ化するとき,それを利用するソースから,そのテンプレート関数の実装(定義)も含めてインクルードしなければならない.そうしないと,特定の型に対してテンプレート関数のインスタンスを生成できないからだ.しかし,この仕様には ヘッダファイルの肥大化(コンパイル速度の低下) 望ましくない実装の公開 などの問題がある.これを回避するために,特定の型に対してテンプレートのインスタンスを明示的に生成する explicit instantiation という方法がある. explicit instantiation はテンプレートの特殊化 (explicit specialization) とは別物なので注意しなければならない.後者は,特定の型に対して特定の実装を与えるためのものだ. さて,引数の2乗を返すテンプレート関数 template <typen
CやC++で書かれたプログラムをMakeを使ってビルドする、というのはUnix/Linuxではよく行われていることだが、ちゃんとしたMakefileを書くのは意外と難しい。 例えば以下の3つのファイルからなるプログラムを考える。 foo.h: 関数fooの宣言がある。 foo.c: 関数fooの実装がある。 main.c: 関数fooを呼び出す。 /* foo.h */ void foo(int a); /* foo.c */ #include "foo.h" #include <stdio.h> void foo(int a){ printf("%d\n", a); } /* main.c */ #include "foo.h" int main(int argc, char **argv){ foo(10); return 0; } Makefileは例えば以下のように書ける。 PRO
unorderd_setやunorderd_mapのキーに自作クラスを渡す方法です。 set,mapはこちら。 mapでは不等号が必要でしたが、unorderd_mapでは等号とハッシュ関数が必要です。 等号はoperator==で良いのですが、ハッシュ関数の与え方がstd::unorderd_mapとboost::unorderd_mapでは違うようです。 #クラスに同値、ハッシュをもたせる(std版) まずはstd::unorderd_map版です。 std名前空間にテンプレートの特殊化を使ってhashという名前で定義します。 #include <unordered_map> class Point{ public: int x, y; Point(){} Point(int x, int y):x(x),y(y){} bool operator==(const Point &left
# include <map> class Point{ public: int x, y; Point(){} Point(int x, int y):x(x),y(y){} }; int main(){ typedef std::map<Point, int> PointMap; PointMap pmap; return 0; } # include <map> class Point{ public: int x, y; Point(){} Point(int x, int y):x(x),y(y){} bool operator<(const Point &right) const {return this->y < right.y;} }; //クラスの外で定義するならこう //bool operator<(const Point &left, const Point &rig
Cコンパイラのgccコンパイラやg++(C++のコンパイラ)でよく使われる -fPIC オプションと -fpic オプションの違いについてまとめました。また、-fPIC オプションをつけた場合、どのようなアセンブリ言語が生成されるのか、確認しました。 読み方 pic ぴっく position-independent code ぽじしょん いんでぃぺんでんと こーど 概要 Unixでプログラムをビルドしている最中に流れてくるメッセージをみていると、cc(gcc)のコンパイルオプションに -fPIC というオプションがついていることに気がつくと思います。 gccには、-fPIC のほかに -fpic というオプションもあります。小文字か大文字かの違いがありますが、一体何が違うのでしょうか? まず、 -fPIC について解説し、そのあと -fPIC と -fpic の違いについて説明します。 -
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く