distinguishing between static and non-static methods in c++ at compile time?
-
10-07-2019 - |
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)?
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.