34

与えられた

struct A { 
    int foo(double a, std::string& b) const;
};

次のようなメンバー関数ポインターを作成できます。

typedef int (A::*PFN_FOO)(double, std::string&) const;

の署名が変更PFN_FOOされた場合に更新する必要があることを除けば、簡単です。A::fooC++11 では が導入さdecltypeれているため、署名を自動的に推測して typedef を作成するために使用できますか?

4

2 に答える 2

56

はい、もちろん:

typedef decltype(&A::foo) PFN_FOO;

キーワードで型エイリアスを定義することもできますusing(Matthieu M. に感謝):

using PFN_FOO = decltype(&A::foo);

于 2012-10-26T14:50:42.620 に答える
23

1つの問題:この変数が明確である場合にのみ、変数のタイプを推測できます。

関数の主な問題は、オーバーロードは、それらの名前だけでは関数を識別するには不十分であることを意味することです。したがって、 indecltypeの過負荷が発生した場合、使用は失敗します。fooA

struct A {
    void foo() const;
    void foo(int) const;
};

using PFN_FOO = decltype(A::foo);
source.cpp:6:36: error: decltype cannot resolve address of overloaded function

このように多くを得ることができるかどうかはわかりません...

一方、実際にエイリアスを使用して、エイリアスが正しいことを確認できます。

struct A {
    void foo() const;
    void foo(int) const;
};

using PFN_FOO = void (A::*)(int) const;

static_assert(std::is_same<PFN_FOO, decltype(static_cast<PFN_FOO>(&A::foo))>::value,
     "Ooops, need to update signature of PFN_FOO!");

注:これがテストの最良の方法かどうかはわかりません。基本的に必要なのはstatic_castパーツだけです。エラーメッセージを一緒に隠したかっただけです。ただし、より良いメッセージを取得するには、おそらくSFINAEのようなものが必要になります。

于 2012-10-26T17:29:48.110 に答える