Hey guys, I have some code and I'm having trouble understanding why my default constructor call isn't being treated as an rvalue reference. The STL accepts it properly so it must be something with my implementation, I'm just having trouble seeing where...
Code:
template<class T>
class Element {
private:
char buffer[sizeof(T)];
bool alive_;
public:
Element(void) {
std::cout << "calling Element default constructor" << std::endl;
alive_ = false;
memset(&buffer, 0, sizeof(T));
}
Element(const T &t) {
std::cout << "calling Element(T) copy constructor" << std::endl;
new(buffer) T(t);
alive_ = true;
}
Element(T &&t) {
std::cout << "calling Element(T) move constructor" << std::endl;
new(buffer) T(std::move(t));
alive_ = true;
}
~Element(void) {
std::cout << "calling Element destructor" << std::endl;
if (alive_) {
T *tmp = (T* ) buffer;
tmp->~T();
alive_ = false;
}
}
T& operator*(void) {
T *tmp = reinterpret_cast<T*>(buffer);
return *tmp;
}
};
with test code:
Code:
struct MyStructure {
int *data;
int size;
MyStructure(void) {
std::cout << "calling MyStructure default constructor" << std::endl;
size = 256;
data = new int[size];
}
MyStructure(const MyStructure &other) {
std::cout << "calling MyStructure copy constructor" << std::endl;
size = other.size;
data = new int[size];
}
MyStructure(MyStructure &&other) : data(other.data), size(other.size) {
std::cout << "calling MyStructure move constructor" << std::endl;
other.data = nullptr;
other.size = 0;
}
~MyStructure(void) {
size = 0;
delete[] data;
}
friend std::ostream& operator<<(std::ostream &os, MyStructure &a);
};
std::ostream& operator<<(std::ostream &os, MyStructure &a) {
os << a.size;
return os;
}
MyStructure test(void) {
MyStructure tmp;
return tmp;
}
int main(void) {
MyStructure a;
Element<MyStructure> el2(a);
std::cout << *el2 << std::endl;
MyStructure &&rvalue = MyStructure();
Element<MyStructure> el3(std::move(rvalue));
std::cout << *el3 << std::endl;
Element<MyStructure> el4(std::move(MyStructure()));
std::cout << *el4 << std::endl;
// this is the problem one!
Element<MyStructure> el5(MyStructure());
std::cout << *el5 << std::endl;
std::vector<MyStructure> x;
x.push_back(MyStructure());
std::cout << x[0].size << std::endl;
return 0;
}
I've been getting this compilation error which leads me to believe that el5 is actually receiving a function pointer instead of the return from the default constructor call. But it works for std::vector!
Code:
warning: the address of ‘Element<MyStructure> el5(MyStructure (*)())’ will always evaluate as ‘true’ [-Waddress]
std::cout << *el5 << std::endl;