C++ Struct within Struct + deleted function error - c++

I have a header file in a project where I am declaring a number of structs. Some of the latter structs have members that are the types of earlier declared structs. I am aware that these member structs must be declared before they are used but I have encountered an odd behaviour.
In the file below I tried to add a new member to the second struct (LUT) of type Coordinate. As yo can see the bottom struct libraryEntry has a similar member; this has been the case for a while and has caused no problems.
#ifndef STRUCTS_H
#define STRUCTS_H
#pragma once
#include <string>
#include "Enums.h"
struct Coordinate {
int X;
int Y;
Coordinate(int x, int y) : X(x), Y(y) {}
};
struct LUT {
int offset;
std::string hexCode;
bool modifiedByTrojan;
//Coordinate xyCoordinate; <======= Causes build to fail when uncommented
};
struct libraryEntry {
int id;
DeviceType deviceType;
int offSet;
Coordinate xyCoordinate;
std::string hexCode;
DeviceConfiguration deviceConfig;
libraryEntry(int idNum, DeviceType deviceType, int offSet, Coordinate xyCoordinate, std::string hexCode) :
id(idNum),
deviceType(deviceType),
offSet(offSet),
xyCoordinate(xyCoordinate),
hexCode(hexCode)
{
}
};
#endif
Adding the Coordinate member above causes the error:
'LUT::LUT(void)':attempting to refernce a deleted function
Why is this only happening in the second struct?

In the struct that works (libraryEntry), you have defined a constructor, and in your constructor you are initialising xyCoordinate using its two-arg constructor.
In the struct that fails to compile, you haven't defined any constructors, so you get the default no-arg constructor, which initialises everything, including your Coordinate member, using their default (no-arg) constructors. Coordinate doesn't have a default constructor because you declared a different constructor and that causes the default constructor to be deleted, hence your error message.

Related

Enum class defined in header file does not work in struct which is located in another header file?? C++

SomeHeader.h:
enum class TypeEnum
{
None = 0,
BYTE,
UBYTE,
SHORT,
USHORT
};
AnotherHeader.h
struct Structure
{
TypeEnum type;
};
Throws An Error:
C3646 'type': unknown override specifier
EDIT:
Nobody seems to know the reason so am leaving additional info which might not be related:
TypeEnum has 33 Elements in my real code
It's located on top of the header file
Everything works fine in other headers
Other Structs In AnotherHeader.h With TypeEnum don't work as well
When I define TypeEnum in AnotherHeader.h it says enum class redefinition as it should
Changing to TypeEnum to enum instead of enum class does not work
Other enums don' work as well
Code:
SomeHeader.h:
enum class TypeSpec
{
None = 0,
BYTE,
UBYTE,
SHORT,
USHORT,
INT,
UINT,
FLOAT,
DOUBLE,
VEC2,
VEC3,
VEC4,
VEC2I,
VEC3I,
VEC4I,
VEC2U,
VEC3U,
VEC4U,
VEC2D,
VEC3D,
VEC4D,
MAT2,
MAT3,
MAT4,
MAT2I,
MAT3I,
MAT4I,
MAT2U,
MAT3U,
MAT4U,
MAT2D,
MAT3D,
MAT4D
};
AnotherHeader.h:
struct BufferElement
{
const char* name;
TypeSpec type;
unsigned int size;
unsigned int offset;
bool normalized;
BufferElement() : name("none"), type(TypeSpec::None), size(0), offset(0), normalized(false) {}
BufferElement(TypeSpec _type, const char* _name, bool _normalized = false) :
name(_name), type(_type), size(RenderCommand::getTypeComponentCount(type)), offset(0), normalized(_normalized) {}
};
If you've given us all of AnotherHeader.h, where is the include?
#include "SomeHeader.h"
We do this ALL THE TIME. It's trivial. Define something in one header and #include it at the top of anywhere else you need it. Oh, you should also do this at the top of all .h files:
#pragma once
This keeps the file from being included more than once. (It ignores multiple appearances.)
So your entire SomeHeader would look like:
#pragma once
#include "SomeHeader.h"
struct BufferElement
{
TypeEnum type;
};
Assuming you aren't doing weird stuff with namespaces you haven't actually shown us.

Default Argument in non-inline Constructor

I've written a Cell class. When I write constructor with default parameters as inline function, there is no problem
cell.h
Class Cell{
public:
Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
};
But if I want to move that implementation in my source file like this:
cell.h
Class Cell{
public:
Cell(int x, int y, char sign='.');
};
cell.cpp
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
Compiler says:
Reversi.cpp:1144:43: error: default argument given for parameter 3 of ‘Cell::Cell(int, int, char)’ [-fpermissive]
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign){}
^
In file included from Reversi.cpp:7:0:
Reversi.h:16:5: note: previous specification in ‘Cell::Cell(int, int, char)’ here
Cell(int x, int y, char sign='.');
^
You're trying to specify the default parameters in both files. Only do it within the Header File, and the compiler will stop complaining.
cell.h
Class Cell
{
public:
Cell(int x, int y, char sign);
};
cell.cpp
Cell::Cell(int x, int y, char sign='.'):X(x), Y(y), Sign(sign)
{
}
Specify the default argument only in the member function declaration within the class definition in the header. Otherwise all other modules that include the header will know nothing about the default argument.
You may not declare a default argument for the same parameter more than one time in the same declarative region and the compiler says about this.
You can't create two implementations or provide two versions of default parameters.
You should provide default parameters in the header file and provide either inline implementation in the header file or in the correspondent cpp file.
cell.h
#pragma once
class Cell {
public:
Cell(int x, int y, char sign = '.');
int X;
int Y;
char Sign;
};
cell.cpp
#include "cell.h"
Cell::Cell(int x, int y, char sign): X(x), Y(y), Sign(sign) {}

Priority Queue Compilation Error

I'm attempting to compile the code below, but the compiler gives the error
Struct.h:38:9: error: ‘priority_queue’ in namespace ‘std’ does not name a type
Several searches failed to reveal an answer so I'm hoping you guys can help out. The code was partially based on the sample code given at the c++ reference site.
struct aimedShot;
union moveFunc;
struct timeCommand;
struct aimedShot
{
void (*move) (Dot*, SDL_Event&, double x, double y);
double x;
double y;
};
//Holds the kind of function used
union moveFunc
{
void (*notAimed) (Dot*);
aimedShot aimed;
};
//Dot to be operated on and the appropriate operator with time
struct timeCommand
{
Dot* target;
moveFunc command;
int time;
bool type; //True indicates aimed (integer inputs), False indicates unaimed
};
class CompareCommand
{
public:
bool operator()(timeCommand& c1, timeCommand& c2) //Return true if c1 comes first
{
return (c1.time < c2.time);
}
};
typedef std::priority_queue< timeCommand, std::vector<timeCommand>, CompareCommand> commandTimeline;
To be able to use std::priority_queue<> class template you need to #include <queue> standard header.

error: expected constructor, destructor, or type conversion before '&' token for a user defined class in the source file

I am facing an error in one of my projects which I have replicated using a standalone program. I did see several posts pertinent to this, but could not figure out my problem. I am getting the following error with this code : "error: expected constructor, destructor, or type conversion before '&' token"
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
class X
{
private:
int _x;
public:
X(int x) : _x(x) {};
};
class Y
{
private:
typedef boost::shared_ptr<X> X_ptr;
public:
X_ptr& func1();
};
X_ptr& Y::func1()
{
X_ptr p(new X(8));
return p;
};
int main()
{
return 0;
}
Can someon help me with in resolving this error?
There are two problems. First, you forgot to qualify the type name X_ptr:
Y::X_ptr& Y::func1()
// ^^^ ^
// BUT REMOVE THIS!
Second, notice that you are returning a reference to a local variable. Attempting to dereference the value returned by func1() will give you undefined behavior.
Just change the prototype of your function this way:
Y::X_ptr Y::func1()
// ^^^^^
// Returning the smart pointer by value now
{
X_ptr p(new X(8));
return p;
}

Boost d_ary_heap/priority_queue compile error: deleted function

I am using a Dijkstra for finding a shortest path in graph. I used to use std::set but I think a heap could perform better. But I am having troubles using the d_ary_heap or the priority_queue.
This is a simplified version:
#include <string>
#include <inttypes.h> // for uint32_t
#include <boost/heap/fibonacci_heap.hpp>
#include <boost/heap/binomial_heap.hpp>
#include <boost/heap/d_ary_heap.hpp>
#include <boost/heap/priority_queue.hpp>
using namespace std;
struct __attribute__ ((__packed__)) __attribute__((aligned(8)) Cmp {
// Do *not* reorder the following two fields or comparison will break.
const int32_t _id;
const float _cost;
Cmp(int32_t id, float cost) : _id(id), _cost(cost) {
}
};
struct Entry {
Cmp _cmp;
string str = "some variable";
Entry(int32_t id, float cost) : _cmp(id, cost) {}
Entry(Entry &&e) : _cmp(e._cmp._id, e._cmp._cost) {}
Entry(const Entry &e) : _cmp(e._cmp._id, e._cmp._cost) {}
};
template<class T>
struct gt_entry: public binary_function <T, T, bool>
{
bool operator()(const T &l, const T &r) const
{
return *(int64_t const *)&l > *(int64_t const *)&r;
}
};
typedef boost::heap::d_ary_heap<
Entry,
boost::heap::arity<2>,
boost::heap::compare<gt_entry<Entry> > > DHeap;
typedef boost::heap::binomial_heap<
Entry,
boost::heap::compare<gt_entry<Entry> > > BHeap;
typedef boost::heap::fibonacci_heap<
Entry,
boost::heap::compare<gt_entry<Entry> > > FHeap;
typedef boost::heap::priority_queue<
Entry,
boost::heap::compare<gt_entry<Entry> > > PQueue;
int main() {
//DHeap h; // Doesn't compile
//PQueue h; // Doesn't compile
//BHeap h; // Works but slower than FHeap
FHeap h; // Works but only 3% performance increase vs std::set
h.push(Entry(1, 500.1));
h.top();
h.pop();
return 0;
}
(I am using the packaging of the _cost and _id to speed up comparison, see C++ Optimize if/else condition if you are interested.)
This seems to be the relevant error line, I guess it has something to do with the move or copy constructor.
.../move.h:177:7: error: use of deleted function ‘Entry& Entry::operator=(const Entry&)’
heaps.cpp:19:8: note: ‘Entry& Entry::operator=(const Entry&)’ is implicitly declared as deleted because ‘Entry’ declares a move constructor or move assignment operator
I am using gcc 4.6 (-std=c++0x) and boost 1.50.
Your gcc version does not implement the rules for implicitly deleted functions correctly. The code works at least with gcc 4.7.
A quick workaround is to declare the move assignment operator Entry& operator=(Entry&&) as well.
In general I wouldn't recommend using C++11 with a compiler that is not completely up-to-date.
Also: You move constructor and copy constructor behave odd. They don't copy/move the string. You might want to change that. If you really only need one string across, make it a static member.