続 CRTPと__declspec(dllexport)

iterator_facadeにも同じ問題を見つけたので、iterator_facadeを使った反復子をdllexportしている箇所を調べてみたところ、Boost.Signalsにありました。

#if BOOST_WORKAROUND(_MSC_VER, <= 1400)
  void decrement();
  void advance(difference_type);
#endif
#if BOOST_WORKAROUND(_MSC_VER, <= 1400)
void named_slot_map_iterator::decrement() { assert(false); }
void named_slot_map_iterator::advance(difference_type) { assert(false); }
#endif

http://lists.boost.org/boost-users/2005/08/12982.php
を見る限りVC++のバグという見解のようです。
じゃ、他のコンパイラはエクスポートすべき関数をどう判定してるの?と思い、BorlandのDLLを確認してみます。

C:\Path-to-dir>tdump hamigaki_audio-bcb58-d-0_40.dll | grep vorbis_encoder_base
File STDIN:
    000187A0   70 0018 hamigaki::audio::detail::vorbis_encoder_base::vorbis_encoder_base()
    0001887C   71 0019 hamigaki::audio::detail::vorbis_encoder_base::~vorbis_encoder_base()
    00018AAC   74 001A hamigaki::audio::detail::vorbis_encoder_base::close()
    000188EC   72 001B hamigaki::audio::detail::vorbis_encoder_base::open(void *, long, long, float, int (*)(void *, const char *, int), void (*)(void *))
    000189D4   73 001C hamigaki::audio::detail::vorbis_encoder_base::open(void *, long, long, const hamigaki::audio::vorbis_encode_params&, int (*)(void *, const char *, int), void (*)(void *))
    00018B84   75 001D hamigaki::audio::detail::vorbis_encoder_base::write_blocks(const float *, int)

あぁ、なるほどwrite_blocks()はエクスポートするけど、write()はエクスポートされないわけですか。write()の実装はarbitrary_positional_facade.hppにインラインで存在するから問題なし、ということですね。
というわけで、Boost.Signalsと同じ対処をしました。
http://hamigaki.sourceforge.jp/hamigaki/iostreams/arbitrary_positional_facade.hpp
ちなみにVC++の場合、

         66   41 00005BC0 ?write@vorbis_encoder_base@detail@audio@hamigaki@@QAEH
PBDH@Z = ?write@vorbis_encoder_base@detail@audio@hamigaki@@QAEHPBDH@Z (public: i
nt __thiscall hamigaki::audio::detail::vorbis_encoder_base::write(char const *,i
nt))

write_blocks()でなく、write()をエクスポートしていました。だから、不要なメンバ関数まで実装する必要があったんですね。