Search code examples
c++sfinaeostream

Print class identifier if it is available


The goal is to create a (macro?) that would print a unique identifier per class instance (for example, the this pointer) when it is placed in a class function, and nothing (or something else) when used in a 'normal' function. Preferably without adding anything to the class, but if that is the only way to do it, I'll take it.

Here is my attempt, however it does not like the use of this at all (replacing it with (void)1 makes it work, but I want a unique identifier per class instance. On gcc this errors out like: error: invalid use of ‘this’ in non-member function, and msvc has similar errors: error C2355: 'this': can only be referenced inside non-static member functions or non-static data member initializers

non-working code:

#include <iostream>

class _detect_class_ {};
typedef int _class_sentinel_;

#define THIS_PTR std::is_same<_detect_class_, _class_sentinel_>::value ? (void*)this : nullptr
#define TRACK_THIS_OBJECT typedef _detect_class_ _class_sentinel_;

struct thisptr
{
    void* Ptr;
    thisptr(void* ptr): Ptr(ptr){;}
};

std::ostream& operator<<(std::ostream& strm, const thisptr& p)
{
    if (p.Ptr)
        strm << "Object:" << p.Ptr;
    else
        strm << "No object";
    return strm;
}

#define PRINT_ME    std::cout << thisptr(THIS_PTR) << std::endl;

struct TestStruct
{
    void Function1()
    {
        PRINT_ME;
    }
    TRACK_THIS_OBJECT
};

int main()
{
    TestStruct o1, o2;
    PRINT_ME;       // No object
    o1.Function1(); // Object: (identifier1)
    o2.Function1(); // Object: (identifier2)
    return 0;
}




Solution

  • Maybe this is too simple for advanced C++ gurus

    // this is in header pretty_print.h
    #include <iostream>
    inline void pretty_print() {}
    
    #define PRINTABLE                                                              \
      void pretty_print() { std::cout << this << std::endl; }
    #define PRINT_ME pretty_print()
    // end of header
    
    // #include "pretty_print.h"
    void moo() { PRINT_ME; }
    
    struct Foo {
      PRINTABLE
    
      void foo() { PRINT_ME; }
    };
    
    int main() {
      PRINT_ME;
      moo();
      Foo().foo();
    }