C++

[C++]自称世界最速の文字列数式計算ライブラリを作った。

更新情報 2021年1月 C++標準への要求をC++14からC++17に変更しました。 ベクトル、行列をadapt::Vector<double>、adapt::Matrix<double>からEigenのVectorXd、MatrixXdに、文字列をadapt::Stringからstd::stringに変更しました。 上の変更に伴い、線形代数ライブラリEigenを</double></double>…

[C++]enumを文字列に変換する汎用的な方法。

C++

2021年9月28日追記。どういうわけかアクセス数が増えているので、訪問者を混乱させないよういい加減だったサンプルを作り直した。 enumは単なる整数値に名前を付与する手段の一つだ。パラメータの意味がわかりやすくなる上、処理コストの大きな文字列を使わ…

[C++]Gnuplotライブラリを各軸の文字列表示に対応させた。Gnuplotライブラリ更新(2)。

タイトルのとおりである。GitHubで公開しているGnuplotライブラリADAPT-GPM2を、以下の図のように、軸を数値ではなく文字列にできるようにした。 #include <ADAPT/GPM2/GPMCanvas.h> using namespace adapt::gpm2; int main() { std::vector<std::string> x; std::vector<double> y; x.push_back("label-on</double></std::string></adapt/gpm2/gpmcanvas.h>…

[C++]std::decayの役割。

C++

std::decayは放射性のstd::atomicを非放射性へと変換するための機能である(嘘)1。 std::decayはよくわからない機能である。標準ライブラリの実装などを見ていると結構な頻度で見かけたりするのだが、一体何を目的に使用されているのかはすぐには理解できな…

[C++]関数の引数として受け取る固定長配列の長さは指定可能である。

C++

先の記事で配列型の扱いをいろいろ考えていた中で、ふと気がついた。一般に配列を受け取る関数は、配列引数を先頭要素へのポインタの形で受け取らざるを得ず、その配列の要素数を指定できないと思われている。確かに今や枯れ果てたC言語ではそうだった。が、…

[C++]テンプレートによる配列の扱い。std::anyは配列を格納できるのか。

テンプレートは配列型をどのように推定するのか。 C++のテンプレートを使っていて稀に遭遇する問題の一つは、配列の取り扱いである。私はC言語時代の配列を毛嫌いしていて基本的にstd::arrayを使うようにしているのでこの問題には滅多に引っかからないのだが…

[C++]Visual Studio 2019でatl***.hが見つからない問題に対処する。

症状 最近Visual Studio 2019へと環境を移したのだが、これの上でプラットフォームツールセットをVisual Studio 2017(v141)に切り替えてビルドしようとすると、ATL(Active Template Library)がエラーを発するようになった。タイトルのように"atlstr.h"など…

[C++]std::coutやstd::stringをprintf風にフォーマットする。

C++

私はstreamが嫌いである。scanf、printf系の関数を使うほうがよほど分かりやすく間違いも生じにくいと勝手に思っている。特にiomanipを使ったフォーマットは最悪だ。あんな記述コストが大きくて分かりにくい仕組みをどこの阿呆が考えやがったのか。 C++20か…

[C++]QFileDialogで最後に開いたフォルダ。

QFileDialogは最後に開いたフォルダを保存しておき、次にダイアログを開いた時は最初からそのフォルダを開くようになっている1。この“最後に開いたフォルダ”は全てのQFileDialogのインスタンスで共有されているので、その情報はstaticメンバないしグローバル…

[C++]std::make_tuple、std::tie、std::forward_as_tupleの違い。

C++

いずれも引数を纏めてstd::tupleを作成するという意味では共通している。ただしこれら3つの振る舞いはいずれも異なっていて、状況に応じて適切に使い分ける必要がある。簡潔に言えば、std::make_tupleは引数のコピーを作り、std::tieは引数の左辺値参照を作…

[C++]natvisファイルで多次元の動的配列を表示する。

Visual Studioでデバッグしている時、例えばSTLなどの中身を綺麗に整頓された状態で監視することが出来る。これを自作クラスに対しても行うことは出来るのだろうか?私は標準ライブラリでは設計上の問題が生じる場合によく自作の機能を設計して使うのだが、…

[C++]std::anyとは異なる、動的メモリ確保を行わない動的型を作る。

C++

更新情報 2021年3月18日 色々と設計に問題があったので全面的に作り直した。 動機 std::anyはどのような型のインスタンスでも格納でき、かつデストラクタを呼ぶ必要のない便利な機能だ。ただしインスタンスを格納するメモリは動的に確保される場合があり、し…

[C++]等高線表示機能の追加。Gnuplotライブラリ更新(1)。

GitHubで公開しているC++用GnuplotライブラリADAPT-GPM2に等高線表示機能を追加した。Gnuplotが持つ仕様上の問題を吸収するために、ちょっと回りくどい実装になってしまった。 ライブラリについては過去記事を参照。 github.com Gnuplotのpm3dにおける最大の…

[C++]std::common_typeの挙動は直感的ではない。

C++

以前、range-based for loopに非配列変数の一覧を与えるためのHoldRefArray関数を実装していた時、std::common_typeを使うことはできないかと考えたことがある。のだが、これがどうも“共通して変換可能な型”という説明から連想される結果と今ひとつ合致しな…

[C++]多重ループを一つに纏める直積集合イテレータを作ってみた。

C++

Range-based for loopを理解してからというもの、その悪用を色々と思いついてしまって。 今日も小ネタである。実用性はあんまりない。多重ループにすれば良いところを、敢えてそれを統合し一つのループで表現したくなってしまった病的C++erのお遊びだ。唯一…

[C++]ムーブセマンティクスに対応するThreadPool。

プログラミング界隈でよく知られたマルチスレッド処理のためのパターンであるスレッドプール。使用可能なスレッド数を予め定めておき、そこにキュー方式で処理を追加していくもの。走らせたい関数が100個くらいあったとしても、それを順番待ちに追加して逐次…

[C++]テンプレート再帰回数の限界、再帰回数を減らす実装方法。

C++

テンプレートメタプログラミングなどをしていると多用することになる、テンプレートの再帰。実はこの再帰回数には制限がある。C++11ではこの再帰回数は1024回が推奨されており十分に大きい。実際の回数制限はコンパイラによって異なるが、それなりに大きな数…

Visual Studioで64bitコンパイラツールセットを使う方法。C1060への対処。

msvcでテンプレートを大量に使うなど非常に重たいコードをコンパイルしていると、 fatal error C1060: ヒープの領域を使い果たしました。 というエラーが出ることがある。 Visual Studioのデフォルトのコンパイラは未だに32bitである。出力するバイナリが32b…

[C++]std::bindはnon-copyableな引数を束縛できない。

C++

タイトルのとおりである。std::bindはnon-copyableな引数を束縛できないので、rvalue referenceを引数に取るような関数の扱いには注意を要する。 std::bindは、何らかの関数に事前に引数を与えた関数オブジェクトを生成する機能である。事前に引数を与えてお…

DISLIN解説②

解説①に引き続き、本稿ではまだるっこしいことはどうでもいいからグラフを描いてみよう、という趣旨の解説を行う。ちなみに③の予定はない。私がDISLINに愛想を尽かし、使うことを諦めてしまったからだ。 というわけで、ありがちなsin、cos関数をプロットして…

DISLIN解説①

最近、C++でのグラフ描画のためにDISLIN(マックス・プランク研究所開発)を試していた私だが、C++からグラフを描くには多くの場合Gnuplotが選択されるようで、そうでない場合もROOT(CERN開発の統計解析ライブラリ)やせいぜいPLplot(多言語対応のグラフ描…

[C++]std::functionに与える関数はcopy-constructibleでなければならない。

C++

std::functionは関数ポインタも関数オブジェクトもメンバ関数ポインタもまとめて管理することのできるとても便利な機能である。std::functionは"引数"と"戻り値"の型のみ指定されていればよく、それ以上は何も要求しないので、引数と戻り値の等しい関数オブ…

[C++]テンプレートテンプレートパラメータの“テンプレート引数の数”を取得することはできるのだろうか。

C++

例えば次のようなクラステンプレートX、Yがあったとする。 template <class> struct X {}; template <class, class> struct Y {}; Xはテンプレート引数が1個、Yはテンプレート引数が2個である。 このX、Yを次のようなクラステンプレートに与えてみる。このXorYは、与えられたXやY</class,></class>…

pybind11の引数の型に注意。

自作ライブラリのPythonラッパーを作るためにpybind11を導入している私だが、関数引数の型についていくつかのエラーに悩まされたので、備忘録として記しておく。 デフォルト引数の型が適切かどうかはコンパイル時に判定されない。 void func(const std::vect…

[C++]配列でない個別の値を一纏めにしてrange-based for loopで走査、編集したいとき。

C++

先日は複数のコンテナをrange-based for loopで同時に走査する方法を書いたが、今回は配列になっていない同じ型の変数についてループする話。例えばint型の変数i1~i5がある時、i1~i5までをループしたくなったらどうするのか。 よくある方法としては、波括…

[C++]ラムダ式をオーバーロードする。

C++

C++17未満で使える自作Variantを実装する最中、visit関数の動作を調べている中で偶然見つけ、衝撃を受けた。C++のラムダ式は擬似的にオーバーロードすることができる。 #include <iostream> #include <string> template <class ...Ts> struct OverloadedLambda; template <class T, class ...Ts> struct Overloaded</class></class></string></iostream>…

[C++]継承関係を跨ぐメンバ関数テンプレートのSFINAEには注意すべし。

C++

基底クラスと派生クラスとの間で、同じ関数名、同じ引数、同じ戻り値のメンバ関数をそれぞれ定義し、SFINAEによってそれらを呼び分けることが出来ないかと考えたことがある。 例えば次のようなコードがあったとする。 struct Base { template <class T, std::enable_if_t<std::is_integral<T>::value, std::</class>…

[C++]range-based for loopはindexを持てるし、複数のコンテナの同時走査だってできる。ちょっとだけ頑張れば。

C++

※本記事の内容をC++20の<ranges>に対応するように更新した記事があります。C++20を使用中の方はそちらを参照してください。->std::ranges::views::zip、enumerateの代替機能を作ってみる。 私はrange-based for loopを十分に扱えていなかったのだと思い知った今日こ</ranges>…

[C++]コンパイル時と実行時の橋渡し。

C++

モダンC++では、できるだけコンパイル時に処理をして実行時のコストを軽減する設計が望ましいとされる。それは高速化やポリモーフィズムという観点では確かに正しいのだが、往々にして面倒な状況を生む。例えばstd::tuple<...> tに格納した各値について、実…

C++用のGnuplotラッパーライブラリを一般公開することにした。

タイトルのとおりである。ADAPT-GPM2という名前のライブラリだ。 github.com C++によるグラフ描画のためのライブラリは意外と見つかる。CERN開発の統計解析ライブラリであるROOT、マックス・プランク研究所開発のDISLIN、その他PGPLOTやPLplot、比較的小規模…