By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,233 Members | 1,880 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,233 IT Pros & Developers. It's quick & easy.

Compile typedef-ed substrings

P: n/a
Hi folks! I'm trying to do something that I'm pretty sure you can't do
in C++. But what the heck! Maybe it can work...

I want to figure out how to use macros and templates to turn the
following code snippet:

void SomeClass::someFunction() { /* ... */ }

Into:

void SomeClass::someFunction() { typeid(SomeClass); }

So far, I haven't figured much out. Consider the following macro:

#define FOO(f) f typeid(#f);

It will turn:

void FOO(SomeClass::someFunction() {) /* ... */ }

into:

void SomeClass::someFunction() { typeid(SomeClass::someFunction {); }

Which of course won't compile. The preprocessor is very limited, and
can't parse apart macro arguments. I'm wondering if there's some way to
do it with templates. For instance:

#define FOO(f) f typeid(mymagictemplate<#f>::type);

Any ideas? So far I've come up short.

Thanks,
--Steve (sg****@darwin.cwru.edu)

Jul 23 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
mrstephengross wrote:
Hi folks! I'm trying to do something that I'm pretty sure you can't do
in C++. But what the heck! Maybe it can work...

I want to figure out how to use macros and templates to turn the
following code snippet:

void SomeClass::someFunction() { /* ... */ }

Into:

void SomeClass::someFunction() { typeid(SomeClass); }
Huh? Perhaps you should simply use the search-and-replace feature of
your text editor?
So far, I haven't figured much out. Consider the following macro:

#define FOO(f) f typeid(#f);

It will turn:

void FOO(SomeClass::someFunction() {) /* ... */ }

into:

void SomeClass::someFunction() { typeid(SomeClass::someFunction {); }
No joke... :-/
Which of course won't compile. The preprocessor is very limited, and
can't parse apart macro arguments. I'm wondering if there's some way to
do it with templates. For instance:

#define FOO(f) f typeid(mymagictemplate<#f>::type);
Something similar to

template<void (T::*f)()> struct mymagictemplate {
typedef T type;
};

but do lose the #.
Any ideas? So far I've come up short.


Can you maybe specify the problem you're trying to solve instead of giving
a non-working "solution" and make use *guess* the problem?

V
Jul 23 '05 #2

P: n/a
> Can you maybe specify the problem you're trying to solve instead of
giving
a non-working "solution" and make use *guess* the problem?


Sure... We want to automagically extract the class name from any given
function definition and *use* it in the code. So for any given
function:

SomeClass::foo() { /* ... */ }

We want to automagically turn it into:

SomeClass::foo() { typeid(SomeClass); }

Or even:

SomeClass::foo() { std::cout << typeid(SomeClass).name(); }
(For debugging purposes)

We need to find a way to do it automatically so that we can apply it
across-the-board to the whole program and produce complete debugging
information.

Ideas?

--Steve

Jul 23 '05 #3

P: n/a
mrstephengross wrote:
Can you maybe specify the problem you're trying to solve instead of


giving
a non-working "solution" and make use *guess* the problem?

Sure... We want to automagically extract the class name from any given
function definition and *use* it in the code. So for any given
function:

SomeClass::foo() { /* ... */ }

We want to automagically turn it into:

SomeClass::foo() { typeid(SomeClass); }

Or even:

SomeClass::foo() { std::cout << typeid(SomeClass).name(); }
(For debugging purposes)

We need to find a way to do it automatically so that we can apply it
across-the-board to the whole program and produce complete debugging
information.

Ideas?


How about 'typeid(*this)' ? There are other things that can help
extracting class out of references (if you're so inclined)...

template<class T> struct deref { typedef T type; };
template<class T> struct deref<T&> { typedef T type; };
template<class T> struct deref<T const&> { typedef T type; };
...

(this is for illustration only, I've seen it somewhere, you should try
it before you buy)

Later on, you will actually have 'decltype', it's in the works.

Keep in mind that 'type_info::name' doesn't have to return anything of
any value to the debugger. It's not specified to be extremely useful,
just barely, and depends very much on the implementation.

V
Jul 23 '05 #4

P: n/a
The problem with 'typeid(*this)' is that the function may be static, in
which case 'this' is not available...

--Steve

Jul 23 '05 #5

P: n/a
mrstephengross wrote:
The problem with 'typeid(*this)' is that the function may be static, in
which case 'this' is not available...


I am honestly not sure what you hope to get out of it. If you have to
edit your code *anyway*, why don't you just use the class name instead of
some obscure macro or a template?

V
Jul 23 '05 #6

P: n/a
> > The problem with 'typeid(*this)' is that the function may be
static, in
which case 'this' is not available...
I am honestly not sure what you hope to get out of it. If you have

to edit your code *anyway*, why don't you just use the class name instead of some obscure macro or a template?


Let's say you've got the following code:

==========================================
class foo { void func1(); void func2(); void func3(); ... void funcX();
};

void foo::func1() { ... }
void foo::func2() { ... }
void foo::func3() { ... }
....
void foo::funcX() { ... }
==========================================

I'm trying to find a *quick* way to get the class name printed when
each function executes. If I do it with a macro, then I want that macro
to be very short and easy to insert, given the large number of
functions I'm dealing with:

==========================================
class foo { void func1(); void func2(); void func3(); ... void funcX();
};

#define MACRO(f) f std::cout << typeid(magictemplate<#f>::type);

void MACRO(foo::func1() {) ... }
void MACRO(foo::func2() {) ... }
void MACRO(foo::func3() {) ... }
....
void MACRO(foo::funcX() {) ... }
==========================================

Obviously, I could make the macro take class name as an argument, but
the code will get wordier and less readable:
==========================================
class foo { void func1(); void func2(); void func3(); ... void funcX();
};

#define MACRO(classname, f) f std::cout << typeid(classname);

void MACRO(foo, foo::func1() {) ... }
void MACRO(foo, foo::func2() {) ... }
void MACRO(foo, foo::func3() {) ... }
....
void MACRO(foo, foo::funcX() {) ... }
==========================================

Since I want the macro to be as non-intrusive as possible, I want to
see if there's a way to extract the classname portion of the function
definition at compile time. (I can do it at runtime, but I'll run into
namespace issues: NAMESPACE1::fooclass might be reported as 'fooclass'
instead of 'NAMESPACE1::fooclass').

--Steve

Jul 23 '05 #7

P: n/a

mrstephengross wrote:
I'm trying to find a *quick* way to get the class name printed when
each function executes. [...] I want to
see if there's a way to extract the classname portion of the function
definition at compile time. (I can do it at runtime, but I'll run into namespace issues: NAMESPACE1::fooclass might be reported as 'fooclass' instead of 'NAMESPACE1::fooclass').


The following method seems to be easier than what you have in mind, and
works with namespaces. It uses g++'s __PRETTY_FUNCTION__ variable. You
should be able to find similar features if your compiler is different.

Ali

#include <iostream>
#include <ostream>
#include <string>
#include <assert.h>

#define FUNCTION_INFO \
do \
{ \
std::cout \
<< "::" \
<< pluckClassName(__PRETTY_FUNCTION__) \
<< '\n'; \
} \
while (0);

std::string pluckClassName(std::string const & prettyName)
{
using std::string;

string::size_type beg = prettyName.find(" ");

// We expect a space after the return type
assert(beg != string::npos);

++beg; // Jump over the space
string::size_type end = prettyName.rfind("::");

return ((end == string::npos)
? ""
: prettyName.substr(beg, end - beg));
}

namespace Namespace
{

class Class
{
public:

void foo() { FUNCTION_INFO; }
};

} // Namespace

class FreeClass
{
public:

void bar() { FUNCTION_INFO; }
};

int freeFunction()
{
FUNCTION_INFO;
return 0;
}

int main()
{
Namespace::Class nc;
nc.foo();

FreeClass fc;
fc.bar();

freeFunction();
}

Jul 23 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.