Reputation: 815
namespace first {
namespace second {
class Third {
static void foo() {
std::cout << "foo\n";
}
};
}
}
void bar() {
std::cout << "bar\n";
}
#define first::second::Third::foo bar//this doesn't work
so, what's the correct way to map a nested function to another one?
a more similar situation is:
struct ReleaseVersion {
static void foo() {
std::cout << "release version\n";
}
};
struct DebugVersion {
static void foo() {
std::cout << "debug version\n";
}
};
#ifdef _DEBUG
#define ReleaseVersion::foo DebugVersion::foo
#else
#define DebugVersion::foo ReleaseVersion::foo
#endif
what I want to do is just like malloc and _malloc_dbg, when #define _CRTDBG_MAP_ALLOC, in debug mode, malloc will be mapped to _malloc_dbg, and in release mode, _malloc_dbg will be mapped to malloc
a more more similar situation is:
namespace first {
namespace second {
struct ReleaseVersion {
static void foo() {
std::cout << "release version\n";
}
};
struct DebugVersion {
static void foo(const char* file, long line) {
std::cout << "debug version\n";
}
};
}
}
#ifdef _DEBUG
#define ReleaseVersion::foo() DebugVersion::foo(__FILE__, __LINE__)
#else
#define DebugVersion::foo(file, line) ReleaseVersion::foo()
#endif
so, these 2 version of functions may have different parameters, I cannot just call one. I know I can just do this
#ifdef _DEBUG
#define Foo() first::second::DebugVersion::foo(__FILE__, __LINE__)
#else
#define Foo() first::second::ReleaseVersion::foo()
but in this way, I must always use Foo(), even in the final release mode, it's still a macro. I want to know if there are more flexible way to to do this.
#ifdef _DEBUG
#define foo() foo(__FILE__, __LINE__)
#define ReleaseVersion DebugVersion
#else
#define foo(file, line) foo()
#define DebugVersion ReleaseVersion
#endif
int main() {
first::second::DebugVersion::foo(__FILE__, __LINE__);
first::second::ReleaseVersion::foo();
return 0;
}
it may be dangerous when there are another foo() or RealeaseVersion/DebugVersion in other namespaces, but if you can make sure there won't, I think it can be an acceptable solution.
Upvotes: 0
Views: 3056
Reputation: 181
I would rather using inline functions
#ifdef _DEBUG
static inline void DoFoo() { DebugVersion::foo(); }
#else
static inline void DoFoo() { ReleaseVersion::foo(); }
#endif
Upvotes: 0
Reputation: 129524
The way malloc
/free
works is by a macro replacement:
#ifdef WANT_DEBUG_MALLOC
#define malloc(x) debug_malloc(x, __FILE__, __LINE__)
#define free(x) debug_free(x, __FILE__, __LINE__)
#endif
When the preprocessor sees struct foo *p = malloc(sizeof(struct foo) * 10);
it will replace it with struct foo *p = debug_malloc(sizeof(struct foo) * 10, "myfile.c", 103);
However, as mentioned above, you can't really use namespaces when doing the macro replacement. You have to EITHER replace the namespace alone, or replace the function name alone. Of course, it's possible to have two macros, one to substitute the namespace, and one for substituting the function name. But it gets pretty messy pretty quickly, so best avoided, I'd say.
Upvotes: 1
Reputation: 55639
Your #define
is the wrong way around:
#define bar first::second::Third::foo
means that bar
will be replaced by first::second::Third::foo
, which, I believe, is what you want.
This is the opposite of typedef
, where things are the other way around.
I'm not exactly sure what you want, but this works:
namespace first {
namespace second {
class Third {
public: static void foo() {
std::cout << "foo\n";
}
};
}
}
#define bar first::second::Third::foo
int main()
{
bar();
}
Upvotes: 2