boost::variantのバージョン互換性

  •  
  •  
  • Category:

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

コメントする