c++template-meta-programming

With C++ meta programming, how to figure out whether you are in a class method or static/global function?


Is there a way to figure out whether the current scope is a global function/static class-method or a class-method?

I thought of the existence of this, but I'm unable to find a technique which doesn't error out during compilation when this does not exist.

I'd like to have one function-prototype which I can use in a member-method or global function, but it does behave differently. Without adding something to my classes and without adding additional arguments to my function call.

An example:

class NormalClass
{
public:
    void foo(int a, bool b)
    {
        DEBUG("print from class %d %d\n", a, b);
    }
};

void normal_function()
{
    DEBUG("print from a normal function");
}

Printing out

Class: print from class 1, 2
Global: print from a normal function

Solution

  • If the actual goal is to check whether some specific class data members are visible in the current scope (as clarified in the comments), then you can just declare the same variables in the global scope, but this time giving them a special unique type that can be used later to tell which variable is visible: global one or member one.

    This approach is based on the fact that a member name will hide the name declared in the global or namespace scope.

    Live example: https://godbolt.org/z/xaKK95WE9

    #include <iostream>
    #include <type_traits>
    
    struct TypeOfGlobalProbe;
    static inline TypeOfGlobalProbe* memberName = nullptr;
    
    #define DEBUG_IS_FREE() (std::is_same_v<decltype(memberName), TypeOfGlobalProbe*>)
    
    void test_1()
    {
        std::cout << "Is test_1() a free function? " << DEBUG_IS_FREE() << "\n";
    }
    
    struct Base
    {
        int         memberName;
    };
    
    struct Derived : public Base
    {
        void test_2()
        {
            std::cout << "Is test_2() a free function? " << DEBUG_IS_FREE() << "\n";
        }
    };
    
    int main()
    {
        test_1();
        Derived         d;
        d.test_2();
    }
    

    std::is_same_v<> is a compile-time check that can be used in, for example, if constexpr.