No appropriate default constructor available in struct with glm vectors - c++

in .h:
enum collisionType {AB, BA, AoverB, AunderB};
struct Collision {
public:
collisionType type;
glm::vec2 point1;
glm::vec2 point2;
Collision(enum collisionType, glm::vec2, glm::vec2);
};
in .cpp:
Collision::Collision(enum collisionType collisType, glm::vec2 p1, glm::vec2 p2) : type(collisType), point1(p1), point2(p2)
{
}
using it
std::vector<Collision> collisions;
glm::vec2 point1(11.0, 12.0);
glm::vec2 point2(12.0, 13.0);
collisions.push_back(Collision(AoverB, point1, point2));
Getting error C2512: 'Collision' : no appropriate default constructor available, why?

You can read here the requirements for a type T to be well suited for std::vector.
Default-constructible is not listed there.
I also tried compiling this minimal code sample, in which X doesn't have a default constructor, and it compiles fine with MSVC:
#include <vector>
struct X {
X(int a, int b) : A(a), B(b) {}
int A;
int B;
};
int main() {
std::vector<X> v;
v.push_back(X(10,20));
}
So, the problem must be elsewhere in your code.
Anyway, you may want to add a constructor with no arguments to make your Collission class "default-constructible", and make the compiler happy:
struct Collision {
// Default constructor.
// Initialize data members to some init values.
Collision() {
...
}
PS Note that struct in C++ is equivalent to class { public: ..., so you can omit the public: line in your code: it's implied by the use of the keyword struct.

The following code compiles fine, it's something else that is the problem.
#include <glm/vec2.hpp>
#include <vector>
enum collisionType {AB, BA, AoverB, AunderB};
struct Collision {
public:
collisionType type;
glm::vec2 point1;
glm::vec2 point2;
Collision(enum collisionType, glm::vec2, glm::vec2);
};
Collision::Collision(enum collisionType collisType, glm::vec2 p1, glm::vec2 p2) : type(collisType), point1(p1), point2(p2)
{
}
int main()
{
std::vector<Collision> collisions;
glm::vec2 point1(11.0, 12.0);
glm::vec2 point2(12.0, 13.0);
collisions.push_back(Collision(AoverB, point1, point2));
}

Related

how to get a class to take in another classes parameters?

I want to have my grid class constructor to take in drivers_location parameters , but it keeps giving me these errors.
https://imgur.com/a/y4MZqso
#include <iostream>
#include <string>
using namespace std;
class drivers_location {
public:
drivers_location() = default;
drivers_location(string name, float xx, float yy){
x = xx;
y = yy;
name = driver_name;
}
private:
float x{};
float y{};
string driver_name;
};
class grid {
public:
grid() = default;
grid(drivers_location(string name, float xx, float yy));
private:
};
int main() {
drivers_location p;
float pointx{ 2.0 };
float pointy{ 3.0 };
grid m[5];
m[0] = { {"abdul" , pointx, pointy }};
}
I want the grid to take in parameters of drivers_location without using inheritance if that's possible
The correct syntax for declaring a constructor takes argument of type driver_location is as shown below. Note that you don't have to specify the 2 parameters of driver_location when defining the constructor for grid that has a parameter of type driver_location.
class grid {
public:
grid() = default;
//---vvvvvvvvvvvvvvvv---->this is how we specify that this ctor has a parameter of type drivers_location
grid(drivers_location){
//add your code here
}
private:
};
I would also recommend using a good c++ book.

using predefined structs in c++ in functions

so i am trying to build a game and i have the following code:
// Vector2 is just a struct that represents a vector is 2D space.
// predefining these structs
struct SILO;
struct ICBM;
struct MISSILE;
struct ICBM{
Vector2 launch;
Vector2 target;
Vector2 pos;
int Velocity;
ICBM(){
// Implementation not shown
}
void move(){
// implementation not shown
}
};
struct MISSILE{
Vector2 launch;
Vector2 target;
Vector2 pos;
int Velocity;
MISSILE(Vector2 t, SILO origin){
launch = (Vector2) {origin.Object.x, origin.Object.y};
target = t;
pos = launch;
Velocity = 10;
}
void move(){
// implementation not shown
}
};
struct SILO{
Rectangle Object; // Rectangle has attributes x and y
Vector2 pos;
};
I predefined all of the structs in the beginning so they can reference eachother. However, the constructor of the struct MISSILE will result in an error saying that SILO is an incomplete type.
I could change the constructor parameter into MISSILE(Vector2 t, SILO* origin). However, when i try to access the attributes, it will result in the same error.
Is there any way I can solve this problem WITHOUT changing the position of where SILO is defined?
You could use a SILO* in your MISSILE constructor, instead a copy of the whole object?!
MISSILE(Vector2 t, SILO* origin){
launch = (Vector2) {origin->Object.x, origin->Object.y};

What is the scope of a class inside of a class in C++?

I've written a class that looks like
class Mesh {
public:
vector<Vertex> vs;
}
where Vertex is
class Vertex {
public:
const double x, y, z;
}
I have a function which loads a Mesh from a file:
shared_ptr<Mesh> load_mesh(string filename) {
//....
vector<Vertex> vs;
Vertex v(1, 2, 3);
vs.push_back(v);
return shared_ptr<Mesh>(Mesh(vs));
}
My questions are concerning the scope of the Vertex and the vector.
Will one or both go out of scope?
Which (if any) of the alternatives are preferred?
class Mesh1 {
public:
vector<shared_ptr<Vertex>> vs;
}
class Mesh2 {
public:
shared_ptr<vector<Vertex>> vs;
}
class Mesh3 {
public:
shared_ptr<vector<shared_ptr<Vertex>>> vs;
}
Or is there a better / easier way of handling this?
Your basic structure looks right to me. You are copying the Vertex into the vector and then copying the vector into the Mesh. The local copies in the load_mesh() function will go out of scope but because you have made a copy that is ok.
At the risk of being accused of premature optimization I would say that unless the vector is small all that copying is a little inefficient. There are a number of ways it could be optimized. With C++11, and move semantics, you can keep your current structure and just move the data:
#include <vector>
struct Vertex {
const double x, y, z;
Vertex(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {}
};
struct Mesh {
std::vector<Vertex> vs;
Mesh(std::vector<Vertex> _vs) : vs(std::move(_vs)) {}
Mesh(Mesh&& other) noexcept : vs(std::move(other.vs)) {} // Move constructor
};
Mesh
loadMesh() {
//....
std::vector<Vertex> vs;
vs.emplace_back(1,2,3);
return Mesh{std::move(vs)};
}
int main() {
auto mesh = loadMesh();
}
I'm using emplace_back instead of push_back to construct the Vertex in the vector in-place and using std::move to move the vector into Mesh.
Returning a shared_ptr<Mesh> would be fine but I wanted to show you can also return the Mesh by value. The compiler should perform RVO and there will be no copy (see this question).

Sorting a std::vector with a compare functor which has access to class members

I want to sort out a vector using std::sort with self-defined comparison function/functor. Inside this function I always want to have access functions or variables defined within the class.
Class MainClass
{
protected: // Variables
float fixedpoint;
protected: // Methods
float DistanceBetweenTwoPoints(float,float);
void function1();
struct CompareDistanceToGoal : public std::binary_function<float,float,bool>
{
bool operator()(float p1, float p2)
{
// return ( p1 < p2);
// I want to use the following code instead of the above
return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
}
};
}
Inside function1:
void MainClass::function1()
{
std::vector<float> V1;
std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal());
}
So instead of using "return (p1 < p2)", I want to have access to fixedpoint and maybe DistanceBetweenTwoPoints() function. Is this possible (i.e. using friend identifier somehow)?
Can anybody show me how to do this? Thanks.
As a nested type, CompareDistanceToGoal has access to all members of MainClass; there's no need to declare it a friend. (Although this is a moderately recent change to the language; a compiler that doesn't implement C++11 might need a friend declaration, friend CompareDistanceToGoal;, to match modern behaviour).
However, since these members are non-static, you can't do anything with those members unless you provide a MainClass object. Perhaps you want to make them static; or perhaps you want to "capture" an object:
struct CompareDistanceToGoal // no need for that binary_function nonsense
{
MainClass & mc;
CompareDistanceToGoal(MainClass & mc) : mc(mc) {}
bool operator()(float p1, float p2)
{
return mc.DistanceBetweenTwoPoints(mc.fixedpoint,p1) <
mc.DistanceBetweenTwoPoints(mc.fixedpoint,p2);
}
};
std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal(some_main_class_object));
It's a bit hard to know what you're trying to do, but this seems to have as much chance of being what you want as anything else... note that MainClass stores a fixedpoint then provides a functor (no need for a nested class) which is then used by sort. In the code below, it sorts the vector so elements closest to the MainClass fixedpoint are earlier in the vector. See it running at ideone.com.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
class MainClass
{
public:
MainClass(float fixedpoint) : fixedpoint_(fixedpoint) { }
bool operator()(float p1, float p2) const
{
float d1 = DistanceBetweenTwoPoints(fixedpoint_,p1);
float d2 = DistanceBetweenTwoPoints(fixedpoint_,p2);
return d1 < d2 || d1 == d2 && p1 < p2;
};
protected: // Variables
float fixedpoint_;
static float DistanceBetweenTwoPoints(float a,float b) { return std::fabs(a - b); }
void function1();
};
int main()
{
std::vector<float> v { 1, 3, 4.5, 2.3, 9, 12 };
std::sort(std::begin(v), std::end(v), MainClass(9.3));
for (auto f : v)
std::cout << f << '\n';
}
you can capture value manually
struct CompareDistanceToGoal : public std::binary_function<float,float,bool>
{
float fixedpoint;
CompareDistanceToGoal(float p) : fixedpoint(p) {}
bool operator()(float p1, float p2)
{
return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
}
};
and use it
void MainClass::function1()
{
std::vector<float> V1;
std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal(fixedpoint));
}
or if C++11 is available, use lambda to capture value
void MainClass::function1()
{
std::vector<float> V1;
std::sort(V1.begin(),V1.end(),[=](float p1, float p2){
return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
});
}

Strange vector initialization issue

I recently debugged a strange C++ problem, in which a newly declared vector somehow had a size of 477218589. Here's the context:
struct Triangle {
Point3 a,b,c;
Triangle(Point3 x, Point3 y, Point3 z) : a(x), b(y), c(z) {}
Vector3 flat_normal() { return (a-c)^(b-c); }
};
vector<Triangle> triangles;
Calling triangles.size() returns the value 477218589.
I 'fixed' the problem by changing struct Triangle to class Triangle, but I'm wondering why there's any difference. Should I have done that typedef struct Foo { ... } Foo; magic? If so, why would that help?
If it matters, I'm using g++-4.1.
This
#include <vector>
#include <iostream>
struct Point3 {};
struct Triangle {
Point3 a,b,c;
Triangle(Point3 x, Point3 y, Point3 z) : a(x), b(y), c(z) {}
};
int main()
{
std::vector<Triangle> triangles;
std::cout << triangles.size() << '\n';
return 0;
}
prints 0 for me. If it also does for you, then the problem is in parts of the code not included in this snippet. If it prints anything else, something is fishy with your compiler/std lib/setup.
There shouldn't be any difference between declaring Triangle as a struct or class - in C++, the difference between the two is that the default access specification of the members is public for struct and private for class, but that's it.
Is there anything more to Triangle that you didn't include?