I have seen anonymous classes in C++ code on Quora. It's successfully compiled and run.
Code here:
#include <iostream>
auto func()
{
class // no name
{
public:
int val;
} a;
a.val = 5;
return a;
}
int main()
{
std::cout << func().val << std::endl;
return 0;
}
So, Is it valid in C++?
Also, I am curious to know, Is it possible to use anonymous classes in C++?
Not only that, you can create more instances of the class by using decltype.
#include <iostream>
class
{
public:
int val;
} a;
int main()
{
decltype(a) b;
a.val = 10;
b.val = 20;
std::cout << a.val << std::endl;
std::cout << b.val << std::endl;
return 0;
}
Output:
10
20
In C++, an anonymous union is a union of this form:
union { ... } ;
It defines an unnamed object of an unnamed type. Its members are injected in the surrounding scope, so one can refer to them without using an <object>. prefix that otherwise would be necessary.
In this sense, no anonymous classes (that are not unions --- in C++ unions are classes) exist.
On the other hand, unnamed classes (including structs and unions) are nothing unusual.
union { ... } x;
class { ... } y;
typedef struct { ... } z;
x and y are named object of unnamed types. z is a typedef-name that is an alias for an unnamed struct. They are not called anonymous because this term is reserved for the above form of a union.
[](){}
Lambdas are unnamed objects of unnamed class types, but they are not called anonymous either.
It was always possible to write something like this:
typedef struct { int a; } type;
Now, if you look at struct { int a } part, this is an anonymous struct. In C++, there's basically no difference between structs and classes (Except the default access modifiers). So, it's possible to have anonymous structs/classes.
Related
I have a class such as
class Stuff
{
private:
int x;
virtual int buisness()
{
return 42;
}
public:
Stuff(){
x = 5;
}
Given a pointer to an instance of this class
Stuff stuff;
void* thing = &stuff;
How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?
Edit: to clarify this was a challenge sent to me and I have been assured that it is not a trick question.
How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?
You can't without casting thing back to the original type:
Stuff* stuff2 = reinterpret_cast<Stuff*>(thing);
and at least that doesn't redeem you from privacy policies of that class, and how you could access class member pointers publicly.
The actual layout is implementation defined, and trying to use offsets from thing and size assumptions is beyond standard c++ mechanisms.
It sounds like you want to circumvent the private member access policies of a class with known layout of these members. Here's an extremely dirty hack:
Disclamer: Don't do that in production code!!
#include <iostream>
class Stuff {
private:
int x;
virtual int business() {
std::cout << "Have that 42 ... " << std::endl;
return 42;
}
public:
Stuff() {
x = 5;
}
};
struct StuffProxy {
// Make the layout public:
int x;
virtual int business();
};
int main() {
Stuff stuff;
void* thing = &stuff;
// Here's the nasty stuff
StuffProxy* stuffProxy = reinterpret_cast<StuffProxy*>(thing);
int* addrX = &(stuffProxy->x); // Get the address of x
std::cout << "x = " << *addrX << std::endl;
typedef int (Stuff::*StuffFunc)();
StuffFunc stuffFunc = (StuffFunc)(&StuffProxy::business);
std::cout << "business() = " << (stuff.*stuffFunc)() << std::endl;
}
Output:
x = 5
Have that 42 ...
business() = 42
Live Demo
The above works because it's guaranteed that class and struct will have the same layout in a c++ compilers implementation, with the only difference of the members visibility during compilation.
So if you have the layout of a class (e.g. from a header), and you are willing to maintain that over the lifetime of your project, you can provide such proxy like above to access the private stuff from a class.
To access the private member x:
1) Declare the function, that needs to access x, as a friend of the class.
2) Change access to public.
3) Write public getter or setter functions.
4) Change your design; Other classes should not know about member variables.
This may be compiler dependant.
I just made a char array from the pointer "thing"
char *array;
array = (char*)thing;
Then traverse that array until I found the private variables
int x = array[8];
Trying to use a unique_ptr inside a union gives me a segfault when I try to std::move or std::make_unique it.
#include <iostream>
#include <memory>
union myUnion{
struct{std::unique_ptr<float> upFloat;}structUpFloat;
struct{std::unique_ptr<int> upInt;}structUpInt;
myUnion(){}
~myUnion(){}
};
struct myStruct{
int x;
myUnion num;
};
int main()
{
myStruct aStruct, bStruct;
aStruct.x = 1;
bStruct.x = 2;
auto upF = std::make_unique<float>(3.14);
auto upI = std::make_unique<int>(3);
aStruct.num.structUpFloat.upFloat = std::move(upF);
bStruct.num.structUpInt.upInt = std::move(upI);
std::cout << "aStruct float = " << *aStruct.num.structUpFloat.upFloat << std::endl;
std::cout << "bStruct int = " << *bStruct.num.structUpInt.upInt << std::endl;
return 0;
}
However, using a normal pointer works as expected:
#include <iostream>
#include <memory>
union myUnion{
struct{float *pFloat;}structPFloat;
struct{int *pInt;}structPInt;
myUnion(){}
~myUnion(){}
};
struct myStruct{
int x;
myUnion num;
};
int main()
{
myStruct aStruct, bStruct;
aStruct.x = 1;
bStruct.x = 2;
auto upF = std::make_unique<float>(3.14);
auto upI = std::make_unique<int>(3);
aStruct.num.structPFloat.pFloat = upF.get();
bStruct.num.structPInt.pInt = upI.get();
std::cout << "aStruct float = " << *aStruct.num.structPFloat.pFloat << std::endl;
std::cout << "bStruct int = " << *bStruct.num.structPInt.pInt << std::endl;
return 0;
}
This is using clang.3.4.2 or gcc.4.9.0. So I'm assuming that I am doing something wrong here. Any help would be appreciated.
EDIT:
Ok, so it's probably a nice thing to do to share the code I settled on. Big thanks to everyone who pointed me to managing the lifetime of my pointers in variant members using placement new.
#include <memory>
#include <iostream>
#include <vector>
struct myStruct
{
public:
union
{
std::unique_ptr<float> upFloat;
std::unique_ptr<int> upInt;
};
enum class unionType {f, i,none} type = unionType::none; // Keep it sane
myStruct(){}
myStruct(std::unique_ptr<float> p)
{
new (&upFloat) std::unique_ptr<float>{std::move(p)};
type = unionType::f;
}
myStruct(std::unique_ptr<int> p)
{
new (&upInt) std::unique_ptr<int>{std::move(p)};
type = unionType::i;
}
~myStruct()
{
switch (type)
{
case unionType::f: upFloat.~unique_ptr<float>(); break;
case unionType::i: upInt.~unique_ptr<int>(); break;
}
}
};
int main()
{
std::vector<std::unique_ptr<myStruct>> structVec;
structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(3.14f)));
structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(739)));
structVec.push_back(std::make_unique<myStruct>());
structVec.push_back(std::make_unique<myStruct>(std::make_unique<float>(8.95f)));
structVec.push_back(std::make_unique<myStruct>(std::make_unique<int>(3)));
structVec.push_back(std::make_unique<myStruct>());
for(auto &a: structVec)
{
if(a->type == myStruct::unionType::none)
{
std::cout << "Struct Has Unallocated Union" << std::endl;
}
else if(a->type == myStruct::unionType::f)
{
std::cout << "Struct float = " << *a->upFloat << std::endl;
}
else
{
std::cout << "Struct int = " << *a->upInt << std::endl;
}
std::cout << std::endl;
}
return 0;
}
Outputs:
Struct float = 3.14
Struct int = 739
Struct Has Unallocated Union
Struct float = 8.95
Struct int = 3
Struct Has Unallocated Union
Changing the active member of a union requires special care to object lifetime. The C++ Standard says (9.5p4):
Note: In general, one must use explicit destructor calls and placement new operators to change the active
member of a union.
When the members are plain old data, it generally "just works", even though you aren't calling constructors (using placement new) and destructors. That's because the lifetime for objects with trivial initialization begins "when storage is obtained" of sufficient size and correct alignment, and the union provides that.
Now you've got members with non-trivial constructor and destructor. Their lifetime doesn't begin when storage is obtained, you also have to cause initialization to finish. And that means placement new. Skipping destructor calls isn't safe either, you get undefined behavior if those destructors would have had side effects your program relies on (and a unique_ptr destructor has the side effect of deallocating its target).
Thus you are calling a move-assignment operator on a member whose lifetime hasn't begun. That is undefined behavior.
For unrestricted union, you have to manage yourself some construct/destruction.
Following may help:
union myUnion{
std::unique_ptr<float> upFloat;
std::unique_ptr<int> upInt;
myUnion(){ new (&upFloat) std::unique_ptr<float>{};}
~myUnion() {}
};
class myStruct
{
public:
~myStruct()
{
destroy();
}
void destroy()
{
switch (type)
{
case unionType::f: num.upFloat.~unique_ptr<float>(); break;
case unionType::i: num.upInt.~unique_ptr<int>(); break;
}
}
void set(std::unique_ptr<int> p)
{
destroy();
new (&num.upInt) std::unique_ptr<int>{std::move(p)};
type = unionType::i;
}
void set(std::unique_ptr<float> p)
{
destroy();
new (&num.upFloat) std::unique_ptr<float>{std::move(p)};
type = unionType::f;
}
public:
enum class unionType {f, i} type = unionType::f; // match the default constructor of enum
myUnion num;
};
int main()
{
myStruct aStruct, bStruct;
aStruct.set(std::make_unique<float>(3.14f));
bStruct.set(std::make_unique<int>(3));
std::cout << "aStruct float = " << *aStruct.num.upFloat << std::endl;
std::cout << "bStruct int = " << *bStruct.num.upInt << std::endl;
return 0;
}
In C++17, you may use std::variant instead of your own struct
From this reference:
If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor) that function is deleted by default in the union and needs to be defined explicitly by the programmer.
I assume that the reason you wrapped the pointers in simple structures is because you could not build it otherwise, due to the restrictions imposed by the above paragraph.
What you have done instead is bypassed the compilers safety-guards, and probably have undefined behavior in your code.
From §12.6.2[class.base.init]/p8 of the standard (emphasis added):
In a non-delegating constructor, if a given non-static data member or
base class is not designated by a
mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no
ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then
if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
otherwise, if the entity is a variant member (9.5), no initialization is performed;
[...]
Union members are variant members, which means that the unique_ptrs are left uninitialized. In particular, no constructor, not even the default one, is called. Technically, the lifetime of these unique_ptrs never even began.
The unique_ptr move assignment operator must delete what the unique_ptr is currently holding, but you are move-assigning to an uninitialized "unique_ptr" containing garbage values. As a result, your move assignment likely caused an attempt to delete a garbage pointer, causing a segfault.
In the comments to this answer, Koushik raised a very valid point.
Take the following:
union U
{
int x;
const T y;
};
(I choose T such that there is no common initial sequence of layout compatibility here, meaning only one member may be active at any given time per [C++11: 9.5/1].)
Since only one member may be "active" at any one time (made active by writing to it), and y cannot be written to after initialisation, isn't this rather pointless? I mean, y can only be read from until the first time x is written to, and at that only if y was the initialised member.
Is there some use case I'm missing? Or is this indeed a pretty pointless confluence of language features?
(This has been mentioned before)
Here's a contrived example of a reference-semantics type where you'd only want to grant const access to. The union is used in a variant-like data type returned from a "type-erasing" function.
#include <memory>
template<class T>
struct reference_semantics
{
public:
reference_semantics(T* p ) : m(p) {}
int observe() const { return *m; }
void change(T p) { *m = p; }
private:
T* m;
};
struct variant
{
enum T { INT, DOUBLE } type;
union U
{
reference_semantics<int> const i;
reference_semantics<double> const d;
U(int* p) : i(p) {}
U(double* p) : d(p) {}
} u;
};
#include <iostream>
std::ostream& operator<<(std::ostream& o, variant const& v)
{
switch(v.type)
{
case variant::INT:
return o << "INT: "<<v.u.i.observe();
case variant::DOUBLE:
return o << "DOUBLE: "<<v.u.d.observe();
}
}
#include <string>
variant type_erased_access(std::string name)
{
// imagine accesses to a map or so
static double dval = 42.21;
static int ival = 1729;
if(name == "Lightness") return { variant::DOUBLE, &dval };
else return { variant::INT, &ival };
}
int main()
{
variant v0( type_erased_access("Lightness") );
std::cout << v0 << "\n";
variant v1( type_erased_access("Darkness") );
std::cout << v1 << "\n";
}
Imagine now that instead of int and double, much larger data types are used, and that the reference_semantics data type actually provides more functionality than just returning the value.
It might even be possible that you want to return a reference_semantics<some_type> const for some arguments, but a plain int for others. In that case, your union might even have const and non-const members.
It does have uses:
1) For offering a const_cast-like technique. In a sense, x = const_cast<...>(y).
2) When dealing with templates, sometimes you need a const version of a data type so you match other parameter types.
(I've seen (1) used when programming against legacy interfaces).
Not using unions a lot, but this might be scenario:
#include <iostream>
class Accessor;
union Union
{
private:
friend class Accessor;
int write;
public:
const int read;
Union() : read(0) {}
};
class Accessor {
public:
static void apply(Union& u, int i) { u.write = i; }
};
int main() {
Union u;
// error: ‘int Union::write’ is private
// u.write = 1;
std::cout << u.read << '\n';
Accessor::apply(u, 1);
std::cout << u.read << '\n';
}
Note: From 9.5 Unions
Note: One special guarantee is made in order to simplify the use of
unions: If a standard-layout union contains several standard-layout
structs that share a common initial sequence (9.2), and if an object
of this standard-layout union type contains one of the standard-layout
structs, it is permitted to inspect the common initial sequence of any
of standard-layout struct members; see 9.2. — end note ]
If the union represents part of a result of some method/algorithm, then it could make sense. But in that case, I'd make both values const:
union T
{
const int x;
const int y;
};
Is there any way to use anonymous classes in C++ as return types?
I googled that this may work:
struct Test {} * fun()
{
}
But this piece of code doesn't compile, the error message is:
new types may not be defined in a return type
Actually the code doesn't make any sense, I just want to figure out whether an anonymous class can be used as return type in C++.
Here is my code:
#include <typeinfo>
#include <iterator>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
using namespace std;
int main(int argc, char **argv)
{
int mx = [] () -> struct { int x, y ; } { return { 99, 101 } ; } ().x ;
return 0;
}
I compile this code with g++ xx.cpp -std=c++0x, the compiler compains:
expected primary-expression before '[' token.
Notice: These code snippets no longer work in the latest versions of g++. I compiled them with version 4.5.2, but versions 4.6.1 and 4.7.0 no longer accept them.
You can declare an anonymous struct as the return type of a lambda function in C++11. But it's not pretty. This code assigns the value 99 to mx:
int mx = [] () -> struct { int x, y ; } { return { 99, 101 } ; } ().x ;
The ideone output is here: http://ideone.com/2rbfM
In response to cheng's request:
The lambda function is a new feature in C++11. It's basically an anonymous function. Here is a simpler example of a lambda function, that takes no arguments and returns an int:
[] () -> int { return 99 ; }
You can assign this to a variable (you have to use auto to do this):
auto f = [] () -> int { return 99 ; } ;
Now you can call it like this:
int mx = f() ;
Or you can call it directly (which is what my code does):
int mx = [] () -> int { return 99 ; } () ;
My code just uses struct { int x, y ; } in place of int. The .x at the end is the normal struct member syntax applied to the function's return value.
This feature is not as useless as it might appear. You can call the function more than once, to access different members:
auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } ;
cout << f().x << endl ;
cout << f().y << endl ;
You don't even have to call the function twice. This code does exactly what the OP asked for:
auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } () ;
cout << f.x << endl ;
cout << f.y << endl ;
Not they can't. As indicated in the error message, from ISO/IEC 14882:2011 8.3.5/9:
Types shall not be defined in return or parameter types. The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within the class).
And you can't, of course, name an existing anonymous type as the return type in a function declaration as an anonymous class has no name.
Although you can create a typedef for an unnamed class and use that as a return type, as the typedef name becomes the name of the class type for linkage purposes the class isn't really anonymous any more.
struct Test {} * a;
decltype(a) fun() {
return a;
}
btw, struct Test {} is not an anonymous struct.
No, you can not do anonymous types like that in C++.
You could however, use typedef to assign anonymous types new names.
typedef struct
{
unsigned x;
unsigned y;
} TPoint;
The closest you can get to what you want is this, in C++14:
auto f() {
struct {
int x, y;
} ret{10,24};
return ret;
}
int main() {
printf("%i", f().x);
}
The struct is anonymous (ret is a variable name, not a type name), and is returned.
You can still get it if needed with
using my_struct = decltype(f());
my_struct another; another.x++;
As #Charles's post pretty much answers the question directly quoting from the spec.
Now, I think why anonymous type cannot be the return type of a function, is because suppose f returns an anonymous type, then what would one write at the calling site?
????? obj = f();
What should be written in place of ????? in the above code?
I want to write a pointer in c++ (or in c++0x), that will points to a operator of a class lets say A or B.
Is there any method to do it?
Of course there is a syntax like
int (A::*_p) ();
but it doesn't solve this problem. I want to make general pointer, not specifying the base class for it - only pointer for "operator function"
#include <thread>
#include <iostream>
using namespace std;
class A
{
public:
int operator()()
{
return 10;
}
};
class B
{
public:
int operator()()
{
return 11;
}
};
int main()
{
A a;
int (*_p) ();
_p = a.operator();
cout << _p();
B b;
_p = b.operator();
cout << _p();
}
No, you can't do this. The class type is a part of the type of the operator member function.
The type of A::operator()() is different from the type of B::operator()(). The former is of type int (A::*)() while the latter is of type int (B::*)(). Those types are entirely unrelated.
The closest you can get is by using something like the C++0x polymorphic function wrapper function (found in C++0x, C++ TR1, and Boost) and by using bind to bind the member function pointer to a class instance:
std::function<int()> _p;
A a;
_p = std::bind(&A::operator(), a);
std::cout << _p();
B b;
_p = std::bind(&B::operator(), b);
std::cout << _p();