Is there any way to detect whether a function exists and can be used at compile time?

后端 未结 1 531
没有蜡笔的小新
没有蜡笔的小新 2021-01-05 08:16

Edit: The short answer to my question is that I had a mistaken view of what SFINAE can do and it does not check the function body at all: does sfinae instan

1条回答
  •  伪装坚强ぢ
    2021-01-05 08:42

    I don't have the time to check this now, but you can add an specialization of Final: template struct Final< Inner >; (which also helps ensure that the type is always a Inner. With that you can extract the type used to instantiate Inter.

    Now the second problem is how to use SFINAE to detect whether a member function exists. I believe this should not be too complex (if you don't need to make this generic):

    // Find out whether U has `void f()` member
    template 
    struct has_member_f {
        typedef char yes;
        struct no { char _[2]; };
        template
        static yes impl( T* );
        static no  impl(...);
    
        enum { value = sizeof( impl( static_cast(0) ) ) == sizeof(yes) };
    };
    

    You might be able to extend this a bit to make it a bit more generic, but the name of the function I don't think you can make generic. Of course, you could write that as a macro that generates has_member_##arg and uses &T:: arg. The type of the member is probably easier to generalize...

    Alternatively, since I don't think this can be made generic, you can use the trick inside has_member directly in your type: provide two callFuncA overloads, one templated with the optional second argument with the signature that you want and defaulted to &T::FuncA that forwards the call, the other with ellipsis that is a noop. Then callFuncs would call callFuncA and callFuncB, and SFINAE will dispatch to either the forwarder or the noon and you get your desired behavior.

    template
    struct Final< Inter >
    {
        template 
        void callFuncA( Inter* x ) {
            x.FuncA();
        }
        void callFuncA(...) {}
    
        void CallFuncs() {
            callFuncA(&t);                 // Cannot pass nonPOD types through ...
            // Similarly TryCallFuncB(t);
        }
        Inter t;
    };
    

    0 讨论(0)
提交回复
热议问题