Is there a way to build a typedef inside a type declaration to the declared (surrounding) type itself without stating the type's name?
Example:
class X
{
public:
typedef <fill in magic here> MyType;
//...
};
Background:
This seems silly on the first look. I need this because I build compile-time-reflection of my data classes using macros.
So there is a macro inserted into the declaration of the data class which needs to deal with the type it is inserted into.
So far I found working solutions for MSVC and g++ which both rely on what I think are flaws in the implementation. So they may not work on a newer version.
Clang does not "eat" either of these solutions.
My current solution for MSVC defines a method and then takes it's address only by it's name and calls a small helper that "returns" the type of it's class. (Clang and g++ expect the full name of the method including it's class name).
My current solution for g++ defines a static method with return type std::remove_reference(decltype(*this)). (Clang and MSVC do not allow this in the static context).
I would absolutely prefer a standard conform solution but a special solution for clang would also be ok for the moment.
If nothing works I have to pass the class' name to the macro but I try to avoid this since I already have plenty of code using the macro.
EDIT: Adding a sample on how the reflection works (which may clarify what I need):
class X : public Y
{
public:
//.. constructor and such stuff...
int a;
double b;
std::string c;
CLASSHEAD(Y)
FIELD(a)
FIELD(b)
FIELD(c)
CLASSFOOT
};
CLASSHEAD is the macro that should define typedef. It is a VAR_ARGS macro where the arguments receive the base classes. As said: It is possible to give it the class' name as it's first argument (resulting in CLASSHEAD(X, Y) in the example). But I nearly cannot imagine that there is no solution to such a "simply" task as typedef'ing the surrounding type...
This doesn't exactly meet your specification, but I think its pretty close:
class X
{
//Stuff...
//Use Macros to add:
struct MyType;
//Use class closing macro to insert variable between class-ending brace and semicolon
} TYPE_VAR;
//Perhaps add random stuff to TYPE_VAR name to avoid collisions, like __FILE__
struct decltype(TYPE_VAR)::MyType
{
typedef decltype(TYPE_VAR) V;
};
Then access X's type using
X::MyType::V
For example, a simplified CLASSFOOT might look like this:
#define CLASSFOOT /*Your classfoot here*/ } TYPE_VAR; struct decltype(TYPE_VAR)::MyType {typedef decltype(TYPE_VAR) V;
//No }; at end on purpose- this will come from the class in which you placed CLASSFOOT
Is this good enough for your purposes?
Since you are already using macros, you could use this solution https://stackoverflow.com/a/21143997/2173029
#define CLASS_WITH_MY_TYPE(ClassName) \
class ClassName \
{ \
using MyType = ClassName;
And then use like
CLASS_WITH_MY_TYPE(X)
public:
struct Y
{
using T = MyType;
};
};
static_assert(std::is_same<X, typename X::Y::T>::value, "");
Marked as community wiki since #Chris mentioned the link and the original answer was posted by #Bartek Banachewicz
Nohting works so using the class Name in the macro is the only working solution
Related
Is it possible to mark an alias of a type as final (i.e. can't be re-defined in derived class)?
#include <iostream>
class B{
public: using type=std::string;
};
class D : public B{
public: using type=int; //<--- [1] I want a compile error here.
};
int main(){
typename D::type str="abc"; //<--- [2] This line is actually correct.
}
According to http://en.cppreference.com/w/cpp/language/final, it is for function only.
Is there a workaround?
It would be useful as a coder fool-proof in some cases.
No, you cannot.
Trait based types could do it, but the machinery is ugly.
Define a distributed type map maybe via an adl based tag function map.
template<class T>struct tag_t{constexpr tag_t(){} using type=T;};
template<class T>constexpr tag_t<T> tag{};
namespace trait {
template<class T>
constexpr void type_tag( tag_t<T> ){}
template<class T>
using type=typename decltype( type_tag( tag<T> ) )::type;
}
// non-final alias
struct A{
friend constexpr tag_t<int> type_tag(tag_t<A>){return {};}
};
// non-final alias
struct A{
friend constexpr tag_t<char> type_tag(tag_t<A>){return {};}
};
// final alias
struct B{
template<class T, std::enable_if_t< std::is_base_of<B,T>{}, bool> =true>
friend constexpr tag_t<std::string> type_tag(tag_t<T>){return {};}
};
now overriding A's type_tag works with trait::type<> but if you try the same with B you'll get a long incomprehensible error.
This is a bad plan.
Metaclasses will probably let you do something like this as well.
In general, both of these require writing a new sublanguage of C++ to enforce a constraint C++ does not enforce. Possible, but ill-advised unless you have an extemely good reason.
Tangential answer on how we could use enums or other dummies to usefully hide a type.
/*
* Imagine everybody uses managed strings in our project throughout,
* so everyone expects to be able to declare and print strings everywhere,
* especially for debugging...
*/
typedef OurInternalMangedStrings string;
/***/
void InternalStringManager::ReallyDoingNastyInternalStuff()
{
// Within this code casually using managed strings
// to format error messages, etc,
// would be fatal as it will cause nasty recursion.
enum DoNotUseStrings_DeadlockDanger { string, OurInternalMangedStrings };
printError(string ("I had an error here and I don't know why - code ") << errCode);
}
This will produce an error which will hopefully mention both string and DoNotUseStrings_DeadlockDanger, giving the clue.
But it is of limited use for types as while it stops the author from using the word "string", it doesn't stop the code from automatically performing conversion, or using objects of that type that already exist, eg the following will pass without comment if the constructor is not explicit:
printError("I had an error here and I don't know why at all!");
For data values I find it is more useful:
void MyManager::Setup()
{
{ SomeFeature newPimple = new Somefeature;
enum DoNotUseMember {someFeature};
/** set up newPimple using other member data and parameters
when it is ready I will assign it to the member variable "someFeature"
**/
/** any accidental use of a someFeature member will produce error message **/
// Ready to install the new pimpl as the visible feature
MUTEX_RAII(access_feature); // ... Or whatever might be needed
/* can still access someFeature by being explicit */
delete this->someFeature;
this->someFeature = newPimpl;
}
/** other setup code that uses the new feature **/
}
Personally, I would call the new instance someFeature and get the hiding behaviour for free, but many find the name reuse hard to read.
Another way I use this technique is in refactoring. I have a method that happily uses member values to control its behaviour, and then an enhancement is needed where one of the control values must be controlled externally. To implement this, the original no-argument method becomes a shim, calling a new method with the member as the argument.
But how to ensure the new method doesn't accidentally use the member instead of the argument? Personally, I'd make the argument mask the member, but we are again limited by the comprehension of others.
I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.
So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.
So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}
You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.
Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};
I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}
I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.
So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.
So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}
You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.
Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};
I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}
I have some code in C, that uses incomplete structs this way ( simplified example ):
something.h
struct something;
struct something *new_something();
int work_a(struct something *something);
int work_b(struct something *something, const char *str);
void free_something(struct something *something);
somecode.c
int some_function()
{
struct something *something;
int x;
something = new_something();
x = work_a(something);
free_something(something);
return x;
}
I was thinking, I'm basically doing C++ here, why not try write it in C++ .
The question is ( I'm new to C++ ), how do I achieve the same in C++ ? If I try to add declare a member function of an incomplete class, I get
error: incomplete type 'something' named in nested name specifier
from clang. By writing the complete class in the header, this would lose the whole point of data hiding, and changing private vars in the class would force every file including "something.h" to recompile, which I think is not needed here. I don't need the files using "something.h" to know the size of this struct / class, I'm usually fine with having just a pointer. I suspected it should look like this:
class Something;
Something::Something();
Something::~Something();
int Something::work_a(int x);
this way I could write the same thing I did in C, only shorter, and even cleaner. Any C++ coder out there wishing to enlighten this mortal C coder?
Take a look at this article: Hiding Implementation Details in C++. It should get you pointed in the direction you are looking. Note that inheritance is being used to accomplish the goal. Also understand that in C++, a struct is a class with all members having public access (includes functions, constructors, and destructors). At a minimum, the interface has to be declared a class, then inherit from that publicly in the now hidden class implementation inside the cpp file (not another header file).
On the Pimpl design pattern, check out this Stack Overflow article: pimpl idiom vs. bridge design pattern. It should also help.
One way to achieve this is through the Pimpl design pattern where you have a pointer to some private struct/class that only your implementation knows about. Your private functions use the pointer and in theory it can be mostly inlined.
When you allocate memory with new statement the compiler has to know how much data space to allocate. The data size of Something has be seen by the compiler before you can use new to create a Something instance.
Use something like this in Something.h
class Something {
public:
Something();
private:
struct HiddenData;
HiddenData* m_pHidden;
};
Use something like this in Something.cpp
struct Something::HiddenData {
int a;
int b;
};
Something::Something() : m_pHidden(new HiddenData()) {
m_pHidden->a = 1;
}
I am using a scoped enum to enumerate states in some state machine that I'm implementing. For example, let's say something like:
enum class CatState
{
sleeping,
napping,
resting
};
In my cpp file where I define a state transition table, I would like to use something equivalent to using namespace X so that I don't need to prefix all my state names with CatState::. In other words, I'd like to use sleeping instead of CatState::sleeping. My transition table has quite a few columns, so avoiding the CatState:: prefix would keep things more compact and readable.
So, is there a way to avoid having to type CatState:: all the time?
Yeah, yeah, I'm already aware of the pitfalls of using namespace. If there's an equivalent for strongly-typed enums, I promise to only use it inside a limited scope in my cpp implementation file, and not for evil.
So, is there a way to avoid having to type CatState:: all the time?
Not before C++20. Just as there's no equivalent for having to type ClassName:: for static class members. You can't say using typename ClassName and then get at the internals. The same goes for strongly typed enums.
C++20 adds the using enum X syntax, which does what it looks like.
You can of course not use enum class syntax, just using regular enums. But then you lose strong typing.
It should be noted that one of the reasons for using ALL_CAPS for weakly typed enums was to avoid name conflicts. Once we have full scoping and strong typing, the name of an enum is uniquely identified and cannot conflict with other names. Being able to bring those names into namespace scope would reintroduce this problem. So you would likely want to use ALL_CAPS again to help disambiguate the names.
So the short answer is no, but fortunately this is going to change in a recently finalized feature set of C++20. According to this accepted proposal you will be able to do the following:
enum class CatState
{
sleeping,
napping,
resting
};
std::string getPurr(CatState state)
{
switch (state)
{
using enum CatState;
// our states are accessible without the scope operator from now on
case sleeping: return {}; // instead of "case CatState::sleeping:"
case napping: return "purr";
case resting: return "purrrrrr";
}
}
You might consider using a typedef to shorten the qualified names:
typedef CatState C;
Or, if the columns are repetitive in a way that they can be generated easily, you might consider using a macro to generate each row in the table, which can lead to very concise (and easier to read) code.
Nicol's answer is correct: the language is designed to make you always qualify scoped enumerators (except in the enum { } scope itself).
However, here is a technique I came up with for "scoped" enumerators that are unscoped within chosen classes. Technically, the enumerators are unscoped, so they will still convert implicitly to int. (Not "strongly-typed" as you put it.) Nevertheless, in the idiom they are accessed using the scope operator after a true enum name, so syntactically there isn't a difference — and therefore it requires C++11.
#define IMPORTABLE_ENUM( TYPENAME, ... ) \
\
struct import_ ## TYPENAME { \
enum TYPENAME { \
__VA_ARGS__ \
}; \
}; \
\
typedef import_ ## TYPENAME :: TYPENAME TYPENAME;
// usage:
IMPORTABLE_ENUM ( duck, huey, dewey, louie )
duck d = duck::dewey; // can't use unscoped enumerators here
struct duck_madness : private import_duck { // but inside a derived class
duck who_did_it() { return huey; } // qualification is unnecessary
};
I would also love to have this possibility and I find the limitation quite annoying. It's usually best to have the programmer decide which features he wants to use. Either explicit scoping or the more convenient way. If you restrict the programmer he will either drop the whole feature for the sake of convenience or invent ugly workarounds, like the following template based type safe enum. It will have a some overhead when compiled without optimization.
template<class _Enum>
class type_safe_enum
{
private:
_Enum m_EnumValue;
operator int();
public:
inline operator _Enum() const { return m_EnumValue; }
inline void operator =(_Enum x) { m_EnumValue = x; }
};
enum _MY_ENUM
{
Value1,
Value2
};
enum _MY_ENUM2
{
Value3,
Value4
};
typedef type_safe_enum<_MY_ENUM> MY_ENUM;
void TestMyEnum()
{
MY_ENUM myEnum;
int x;
myEnum = Value1; // ok
// myEnum = Value3; // compilation error
// myEnum = 0; // compilation error
// x = myEnum; // compilation error
}