I am trying to write a C++ macro that would take either type
or type name
as input, and give type
as output.
For example:REMOVE_NAME(int)
should be int
REMOVE_NAME(int aNumber)
should also be int
I managed to write such a macro (below) and it works, but I'm wondering whether I'm missing a simpler way to accomplish this.
#include <boost/type_traits.hpp>
template <typename T>
struct RemoveNameVoidHelper
{
typedef typename T::arg1_type type;
};
template <>
struct RemoveNameVoidHelper<boost::function_traits<void()>>
{
typedef void type;
};
#define REMOVE_NAME(expr) RemoveNameVoidHelper<boost::function_traits<void(expr)>>::type
Any ideas?
I'm using this macro to aid with code generation. I have another macro which is used to declare certain methods in class definitions:
#define SLOT(name, type) \
void Slot##name(REMOVE_NAME(type) argument) \
{ \
/* Something that uses the argument. */ \
} \
void name(type)
I want the user of the SLOT
macro to be able to comfortably choose whether he wants to implement his slots inside or outside the class, just like with normal methods. This means that SLOT
's type argument can be either a type, or a type with a name. For example:
class SomeClass
{
SLOT(ImplementedElsewhere, int);
SLOT(ImplementedHere, int aNumber)
{
/* Something that uses aNumber. */
}
};
Without the REMOVE_NAME
macro, my automatically generated Slot...
method will not be able to specify its own name for its argument, and thus it will not be able to refer to it.
Of course, this is not the only possible use for this macro.
I think you're correct; as far as I can tell the only other production where a decl-specifier-seq or type-specifier-seq is followed by an optional declarator is a catch
statement, and I don't think that's much use for type extraction. The production parameter-declaration is also used in template-parameter-list, but that's not much use either.
I might define your macro like this, removing the dependency on Boost:
template<typename T> struct remove_name_helper {};
template<typename T> struct remove_name_helper<void(T)> { typedef T type; };
template<> struct remove_name_helper<void()> { typedef void type; };
#define REMOVE_NAME(expr) typename remove_name_helper<void(expr)>>::type
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With