Question

For some tracing automation for identifying instances i want to call either:

  • a non-static method of the containing object returning its identifier
  • something else which always returns the same id

My current solution is to have a base class with a method which() and a global function which() which should be used if not in the context of an object. This however does not work for static member functions, here the compiler prefers the non-static method over the global one.

Simplified example:

class IdentBase
{
public:
  Ident(const std::string& id) _id(id) {}
  const std::string& which() const { return _id; }
private:
  const std::string _id;
};

const std::string& which() { static const std::string s("bar"); return s; }

#define ident() std::cout << which() << std::endl

class Identifiable : public IdentBase
{
public:
  Identifiable() : Ident("foo") {}
  void works() { ident(); }
  static void doesnt_work() { ident(); } // problem here
};

Can i somehow avoid using work-arounds like a special macro for static member functions (maybe using some template magic)?

Was it helpful?

Solution

You might be able to to use is_member_function_pointer from the Boost TypeTraits library. sbi's suggestion of using different code in the static and non-static cases is probably better though.

OTHER TIPS

Define a function template that returns a default identifier for all types.

template<typename T>
const std::string& which(const T& object)
{ static const std::string s("bar"); return s; }

Specialize the function template for the specific class.

class IdentBase
{
public:
    IdentBase(const std::string& id): _id(id) {}
    const std::string& id() const { return _id; }
private:
    const std::string _id;
};

template<>
const std::string& which(const IdentBase& object)
{ return object.id(); }

Call the function template by passing an instance that you want to identify.

int main()
{
    int i;
    std::cout << which(i) << std::endl;

    IdentBase foo("foo");
    std::cout << which(foo) << std::endl;

    return 0;
}

Do you need a different identifier for every instance of each class as in your example, or are you just trying to identify which class is in the trace?

Changing your which() function and _id member to static would expose them both to your static member functions, and as a bonus decrease your memory usage.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top