boost::function_typesのis_member_function_pointer追記

あと、メンバ関数にthrowが付くとおかしくなるみたいです。

#include <iostream>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/is_member_pointer.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
#include <boost/type_traits.hpp>

using namespace std;
using namespace boost;
   
template<typename pT>
void test(pT p)
{
  cout
    << "|" << typeid(pT).name() << "|"
    << is_function<boost::remove_pointer<pT>::type>::value << "|"
    << function_types::is_function_pointer<pT>::value << "|"
    << is_member_function_pointer<pT>::value << "|"
    << function_types::is_member_pointer<pT>::value << "|"
    << function_types::is_member_function_pointer<pT>::value << "|"
    << endl;
}

struct A
{
  void mem1() throw() {}
  void mem2() {}
  void mem3(int) {}
  void mem4() {}
};

void main()
{
  test(&A::mem1);
  test(&A::mem2);
  test(&A::mem3);
  test(&A::mem4);
}

で、

void (__thiscall A::*)(void) 0 0 1 1 0
void (__thiscall A::*)(void) 0 0 1 1 0
void (__thiscall A::*)(int) 0 0 1 1 1
void (__thiscall A::*)(void) 0 0 1 1 0

になります。
同じ関数プロトタイプのものが全滅するのはテンプレートの実体化が同じものになってるからでしょう。
コンパイラのバグであろうと仕様であろうと、ともかく回避したいわけですが、いろいろ試したものの、結局どうにもなりませんでした。
せいぜい、関数のポインタを作る部分でthrow()無しのプロトタイプにキャストするぐらいです。

test((void (A::*)())&A::mem1);

手間としては、オーバーロード時の指定と同じなので、特別面倒でもありませんが、コンパイルエラーが出ないのは困ったものです。関数ポインタ解析の大本であるfunction_types::componentsの内容があからさまに壊れるので、それをBOOST_STATIC_ASSERTすればいけそうですが、他の部分でちゃんとテストやってりゃ大丈夫そうなので、しません。