旧OpenSiv3D(0.4.1~0.4.2)をVisualStudio2019(16.6.3以降)で使うときのエラー対策(最短、最終形態)


原点回帰

プログラミングで仕事的に考えるのは、
同じグループ内で作業把握、チーム内で分かりやすいコード、
費用(作業コスト)対効果
をトップが考えて決める
部内ローカルなコーディングルール

●関数ポインタ使うな
●メンバにm_を使う(え?C#なのに??)
●STLを使わない
●コンストラクタのオーバーロードは使わず、Initメソッドで初期化するルール決め、コンストラクタは引数無しのみにする


など実例(複数社の実例)でいろいろあったりする。それぞれ理由はあってその背景は面白いのだが、長くなるので割愛します。

いっそ、#define で文字列置換の役割を担ってしまえばいいのではないか?
と閃いた。
俺イズム。ローカルルールで作業効率を向上させればいいだけ。

#define は、ややこしくなるで基本はなるだけ使うな、const使え、仕方なく使うとしたら全部半角大文字・・・

このセオリーをしない!作業効率重視!一時的にしないことにより、作業効率を向上させる

前置きが長くなったが、早い話、
昔のプロジェクトが多くある場合、それらをすべていちいち新しいバージョンに変更作業するのは面倒で仕方ない、
これをすぐに確認できる方法は?と考えた次第。

いったん昔のライブラリ本体を書き換えてしまえば、多くある昔のバージョン(0.4.1 0.4.2)はそのまま動作するので楽ができるということ。

準備

VisualStudio2019(16.6.3以降)でOpenSiv3D(0.4.1) または (0.4.2)のプロジェクト
(0.4.0)で試したら、OpenSiv3D の命令系統のエラーが大量に出てしまい、時間がかかりそうなので断念しました。

エラー修正方法

ビルドエラーが出る。result_of 系統の命令で、エラーメッセージをダブルクリックして、
そのヘッダーファイルへ飛び、
下記ソースコードをコピーして1行目に貼り付ければOK!

// C++20 check    std::result_of_t(C++17) ==>> std::invoke_result_t(C++20)

#if _MSC_VER >= 1926

#define result_of_t invoke_result_t
#define result_of invoke_result

#else

#define result_of_t result_of_t
#define result_of result_of

#endif

以上。

他の人に渡すことを考えなければ、上記コード量は半分になります。
他の人は、面倒くさがって新しいVisualStudio2019(16.6.3以降)にバージョンアップしているとは限らないので、それよりも前のバージョンでも動作する仕掛けがあるからです。

以下は、core.h (0.4.1)でエラーが出たので先頭行に追加した例:

発想の転換

#define は半角大文字という暗黙のルールがあったが、それを無視した。
作業量の軽減を考えて文字の置換に特化したため。
道具に過ぎないことは利便性を特化して考える・・・!

あっさりうまくいってしまった。

そもそもこの命令は名称が変わっただけで中身は同じ。引数が増えた機能拡張されただけ。
全く同じ動作は可能。
MSの公式サイトで書かれていた。(サイト先失念)
コメントを頂いたおかげで「あれ?違うんじゃない?そういえば・・・!!」という感じで思い出しました。
「いっそ、こうすればいいんじゃない?」と閃いた感じです。

単純置換

result_ofとinvoke_resultでは引数が1つで考えるならば、全く同じで問題ありません。

置換をしてしまえば全く問題ないということです。

もちろんバージョンダウンで引数が複数あれは問題が起きるとは思いますが、そんな無駄なことをする人はいないことでしょう。

他の命令でもC++のバージョンが変わって変更されても、#defineの単純置換作業か、インラインメソッドを
#if _MSC_VER >= 1926
で振り分けるだけでいい印象がある。