2015-12-02 17 views
17

は、次のコードを考えてみましょう:関数メンバーへのポインタ: `R(* C :: *)(Args ...)`はどういう意味ですか?

template <class> 
struct test: std::integral_constant<int, 0> {}; 
template<class R, class C, class... Args> 
struct test<R(C::*)(Args...)>: std::integral_constant<int, 1> {}; 
template<class R, class C, class... Args> 
struct test<R(*C::*)(Args...)>: std::integral_constant<int, 2> {}; 
template<class R, class C, class... Args> 
struct test<R(**C::*)(Args...)>: std::integral_constant<int, 3> {}; 
template<class R, class C, class... Args> 
struct test<R(C::**)(Args...)>: std::integral_constant<int, 4> {}; 
template<class R, class C, class... Args> 
struct test<R(C::***)(Args...)>: std::integral_constant<int, 5> {}; 

私が何を意味するか(*C::*)(**C::*)(C::**)(C::***)の絶対にないアイデアを持っていません。私はtest<decltype(f)>の例を望んでおり、そのうちvalue2,3,4および5に等しくなります。さらに、その場合、メンバー関数を呼び出すfの構文はどのようになっていますか?

答えて

18

this exampleを考えてみましょう:

R(C::*)(Args...) - メンバ関数へのポインタ:

struct s { 
    void test1(); 
    void(*test2)(); 
    void(**test3)(); 
}; 

int main() { 
    static_assert(test<decltype(&s::test1)>::value == 1); 
    static_assert(test<decltype(&s::test2)>::value == 2); 
    static_assert(test<decltype(&s::test3)>::value == 3); 

    auto test4 = &s::test1; 
    static_assert(test<decltype(&test4)>::value == 4); 

    auto test5 = &test4; 
    static_assert(test<decltype(&test5)>::value == 5); 
} 
ここ

がタイプです。
R(*C::*)(Args...) - 関数ポインタであるデータメンバーへのポインタ。
R(**C::*)(Args...) - 関数ポインタへのポインタであるデータメンバへのポインタ。
R(C::**)(Args...) - メンバ関数へのポインタへのポインタ。
R(C::***)(Args...) - メンバ関数へのポインタへのポインタへのポインタ。これらを呼び出すために

slightly modified example考える:あなたが適切な&[s::]testNの値を持つ変数を持っている場合は、それぞれの場合に、あなたがその変数で(&[s::]testN)を置き換えることができ

struct s { 
    void test1() {std::cout << "test1\n";} 
    void(*test2)() = [] {std::cout << "test2\n";}; 

    void(*test3Helper)() = [] {std::cout << "test3\n";}; 
    void(**test3)() = &test3Helper; 

    void test4() {std::cout << "test4\n";} 
    void test5() {std::cout << "test5\n";} 
}; 

int main() { 
    s obj; 

    auto test4 = &s::test4; 

    auto test5Helper = &s::test5; 
    auto test5 = &test5Helper; 

    (obj.*(&s::test1))(); 
    (*(obj.*(&s::test2)))(); // note that the dereference is unnecessary 
    (**(obj.*(&s::test3)))(); // note that the second dereference is unnecessary 
    (obj.**(&test4))(); 
    (obj.***(&test5))(); 
} 

注意。また、test2とtest3については、説明のために関数ポインタではなく関数を返すまで逆参照しています。

+0

ありがとうございました!もし 's'が関数メンバ' int f(int x){return x;} 'を持っていて、' testN'がそれを参照していれば、変数に 'testN'を実行する構文は何ですか? – Vincent

+0

@Vincent、私はそれに着きました。一秒。 – chris

関連する問題