boost::variant
を使用して共有ライブラリを作成、 そしてそのライブラリを使用するアプリケーションでboost
の新しめのバージョンが必要だったので異なるバージョンのboost
を使用してコンパイル。 すると、リンク時に
undefined reference to `hello(...
ソースはこんな感じ(例)
#include <boost/variant.hpp>
typedef boost::variant<int, std::string, char*> target;
std::string hello(target t);
とりあえず検証してみる
・リンクに失敗したオブジェクト
$ nm --demangle main.cc.o | grep hello
U hello(boost::variant<int, std::string, char*>)
・ライブラリ
$ nm --demangle libhello.so | grep hello
000000000000283c T hello(boost::variant<int, std::string, char*,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_>)
違う。。。
ってかboost::detail::variant::void_
がいっぱい。。。
google先生に聞いても良い答えが返ってこないのでソースを見ていたら発見!
どうやらコレだ!
boost-1.56.0から可変引数テンプレートに対応したようだ。 しかしgcc-4.7未満だと使用しないらしい。ややこしや。。。
gcc-4.7未満 | gcc-4.7以上 | |
boost-1.56.0未満 | × | × |
boost-1.56.0以上 | × | ○ |
ライブラリとそのライブラリをリンクするアプリでこの条件を揃えないといけないという事である。
boost::variant
を使用したライブラリを作成するときは気をつけよう。
ちなみに○のところを×にする(可変引数テンプレートを使わないようにする)ためにはBOOST_NO_CXX11_VARIADIC_TEMPLATES
マクロを設定すれば良い。
(参照:boost/variant/variant_fwd.hpp)