ofxBox2dを使っていたプログラムでofxOpenCvを使用しようとしたらいきなり身に覚えがないところで見に覚えのないコンパイルエラーが発生してしばらくはまっていたのでメモ。
コンパイル時に出るエラーログは下記で始まるやつでした。
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(441): error C2143: 構文エラー : ')' が 'const' の前にありません。
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(441): error C3861: 'dot': 識別子が見つかりませんでした
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(441): error C2059: 構文エラー : ')'
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(448): error C2065: '_Ty' : 定義されていない識別子です。
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(449): error C2143: 構文エラー : ';' が '{' の前にありません。
1>c:program files (x86)microsoft visual studio 10.0vcincludexcomplex(449): error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?)
で、問題(っぽい)xcomplexの441行目付近は下記。
// TEMPLATE FUNCTION norm
_TMPLT(_Ty) inline
_Ty norm(const _CMPLX(_Ty)& _Left)
{ // return squared magnitude
return (real(_Left) * real(_Left) + imag(_Left) * imag(_Left));
}
‘const’の前に’)'がないって言われてるってことは’norm(‘がおかしいんだろうなーと思ったんだけど、ちゃんと関数宣言してるからおかしいところないし・・・と思って次のエラーを見てみると
‘dot’ってなんやねん。
ってことで’#define norm dot’的なやつを探してみると、ありました。(VisualStudio使用なのでF12押しただけですけど)
ofxBox2dPolygonUtils.h(38)
// dot product (3D) which allows vector operations in arguments
//#define dot(u,v) ((u).x * (v).x + (u).y * (v).y + (u).z * (v).z)
#define norm2(v) dot(v,v) // norm2 = squared length of vector
#define norm(v) sqrt(norm2(v)) // norm = length of vector
#define d2(u,v) norm2(u-v) // distance squared = norm2 of difference
#define d(u,v) norm(u-v) // distance = norm of difference
で、ここからはもう別に調べる必要ないんですけど一応。問題の行は
_Ty sqrt(dot(const complex<_Ty>& _Left, const complex<_Ty>& _Left))
こんな風に展開されてて、コンパイラさんに「引数あるなら書いて欲しいんですけど’dot(‘とか知らんしwwwww’const’とか書く前に括弧閉じろしwwwwwww」
って言われてたわけですね。すっきり!でも腹立たしい!
で、とりあえずの解決策としてはofxBox2dPolygonUtils.hよりも前にxcomplexを#includeしてほしいので
ofxOpenCv.hをofxBox2d.hの前に#includeしてやれば通るようになりました。
(ちなみに#include <complex>はopencv2/core/core.hppにあります)
とりあえずはこれでいいけど、根本的にはofxBox2dでこんなに一般的な名前を#defineしてるほうが腹立たしくてしょうがないんですけどね!!!せめて#undefしろ!
(追記)
ofxBox2dPolygonUtils.hの#defineあたりのコードはどうやらofPolyline.cppを元にしているようでした。
僕はlibにビルドして使用してるからcppに書いてある分には問題ないけど、
プロジェクトにoFのソースまで含めて作ってる人(少なからずいると思うんだ)の間で問題になってないんだろうか・・・?