pointer to member

念のためとかせっかくだからで全然意味が違ってきてしまうことに気付いたのでまとめ。ある class の member ( data member でも member function でもいい ) への pointer を取る場合、その関数の qualified-id ( global 名前空間を起点として名前空間や class 名なんかの指定も含めた symbol 、要は絶対指定という理解で大体あってる ) の頭に & をくっつけたものだけが有効らしい。元ネタは http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2010/n3090.pdf の 5.3.1.4 Unary operators ( 俺日本語訳 -> http://github.com/januswel/Cxx0xISja/blob/master/5.3.1%20Unary%20operators%20%5Bexpr.unary.op%5D.txt ) 。

int main(void) {
    struct C {
        void f(void) {
            // ...
        }

        void g(void) {
            void (C::*pf1)(void) = &f;          // NG: unqualified-id
            void (C::*pf2)(void) = &C::f;       // OK
            void (C::*pf3)(void) = &(C::f);     // NG: enclosed by parentheses
        }
    };

    void (C::*pf1)(void) = &C::f;               // OK
    void (C::*pf2)(void) = &(C::f);             // NG: enclosed by parentheses
}

上記の例だと comment で OK と書いてあるものしかダメということだな。一番上は scope 的には見えてるし一意に特定できるハズなんだけど class 名の指定がないので NG 。上から 3 番目と一番下はカッコで括られているので NG 、と。

おれの場合ちょっとややこしい複合式は念のためにわかりやすい単位でカッコで括るひとなので見事に上記の一番下の罠にはまってしまった。というか VS9 が一番下の式を通してしまうってのが一番大きな罠だよなぁ ( 上から 3 番目の式は怒ってくれた ) 。ちなみに g++ は 4.3.3 でちゃんと両方ともダメだと言ってくれる。