Home > Net >  Forward declaration of class and still Error: Variable has incomplete type
Forward declaration of class and still Error: Variable has incomplete type

Time:02-21

I have defined two classes : (1) class Point_CCS_xy , and (2) random_Point_CCS_xy_generator. I would like to define a function in Point_CCS_xy class which makes use of random_Point_CCS_xy_generator class to generate random points on a cartesian coordinate system within a range Min and Max, both of which have been defined as long double. I have already forward declared class random_Point_CCS_xy_generator, however I get an Variable has incomplete type random_Point_CCS_xy_generator error on this line random_Point_CCS_xy_generator rpg(Min, Max); and also this error Member reference base type 'vector<Point_CCS_xy> (size_t)' (aka 'vector<Point_CCS_xy> (unsigned long long)') is not a structure or union, on this line Point_CCS_xy_vec.push_back(p);.

MWE

#include<iostream>
#include<fstream>
#include<functional>
#include<algorithm>
#include<vector>
#include<deque>
#include<queue>
#include<set>
#include<list>
#include<limits>
#include<string>
#include<memory>

using namespace std;
typedef long double ld;

class random_Point_CCS_xy_generator;

class Point_CCS_xy{
private:
    long double x_coordinate_ {0.0};
    long double y_coordinate_ {0.0};
public:
    Point_CCS_xy () = default;
    Point_CCS_xy(long double x, long double y): x_coordinate_(x), y_coordinate_(y) {}
    ~Point_CCS_xy() = default;

    // copy constructor through construction delegation method
    Point_CCS_xy(const Point_CCS_xy& cpyObj) : Point_CCS_xy(cpyObj.x_coordinate_, cpyObj.y_coordinate_)
    {

    }



 // Copy and Mover Assignment Operators, 
 // also setters and getters, and a few utility functions come here inlcuding:
friend ostream& operator<<(ostream& os, const Point_CCS_xy& pnt);


// Problematic Function -> source of ERRORS
vector<Point_CCS_xy> Random_Point_CCS_xy(long double Min, long double Max, size_t n) {
        random_Point_CCS_xy_generator rpg(Min, Max);
        vector<Point_CCS_xy> Point_CCS_xy_vec(size_t);
        for (size_t i = 0; i < n;   i){
            Point_CCS_xy p = Point_CCS_xy(rpg());
            Point_CCS_xy_vec.push_back(p);
        }
        return Point_CCS_xy_vec;
    }
};

ostream& operator<<(ostream& os, const Point_CCS_xy& pnt) {
    os << "X: " << setw(10)<< left << pnt.x_coordinate_ << " Y: " << setw(10)<< left << pnt.y_coordinate_;
    return os;
}

class random_Point_CCS_xy_generator {
public:
    random_Point_CCS_xy_generator(long double min, long double max)
            : engine_(std::random_device()()), distribution_(min, max) {}

    Point_CCS_xy operator()() {
        long double x = distribution_(engine_);
        long double y = distribution_(engine_);
        return Point_CCS_xy(x, y);
    }

    std::mt19937 engine_;
    std::uniform_real_distribution<double> distribution_;
};

As I am a newbie in programming, any idea would be highly appreciated.

CodePudding user response:

You have to complete the definition of that class random_Point_CCS_xy_generator before you can use it in the actual function definition. Probably you will have to move the methods out of a .h file and into an implementation file.

CodePudding user response:

The type must be complete by the time you actually use it (e.g. constructing a value). Forward declaration will only help you specify pointer or reference types, not value types.

Your main issue here is that you're defining your functions inline in the class definition. Instead of that, move them out:

class Point_CCS_xy {
private:
    long double x_coordinate_{ 0.0 };
    long double y_coordinate_{ 0.0 };
public:
    Point_CCS_xy() = default;
    Point_CCS_xy(long double x, long double y) : x_coordinate_(x), y_coordinate_(y) {}
    ~Point_CCS_xy() = default;

    Point_CCS_xy(const Point_CCS_xy& cpyObj);
    vector<Point_CCS_xy> Random_Point_CCS_xy(long double Min, long double Max, size_t n);

    friend ostream& operator<<(ostream& os, const Point_CCS_xy& pnt);
};

class random_Point_CCS_xy_generator {
public:
    random_Point_CCS_xy_generator(long double min, long double max)
        : engine_(std::random_device()()), distribution_(min, max) {}

    Point_CCS_xy operator()() {
        long double x = distribution_(engine_);
        long double y = distribution_(engine_);
        return Point_CCS_xy(x, y);
    }

    std::mt19937 engine_;
    std::uniform_real_distribution<double> distribution_;
};

Then you can define the functions after:

Point_CCS_xy::Point_CCS_xy(const Point_CCS_xy& cpyObj)
    : Point_CCS_xy(cpyObj.x_coordinate_, cpyObj.y_coordinate_)
{
}

vector<Point_CCS_xy> Point_CCS_xy::Random_Point_CCS_xy(long double Min, long double Max, size_t n)
{
    random_Point_CCS_xy_generator rpg(Min, Max);
    vector<Point_CCS_xy> Point_CCS_xy_vec;
    Point_CCS_xy_vec.reserve(n);
    for (size_t i = 0; i < n;   i) {
        Point_CCS_xy p = Point_CCS_xy(rpg());
        Point_CCS_xy_vec.push_back(p);
    }
    return Point_CCS_xy_vec;
}

ostream& operator<<(ostream& os, const Point_CCS_xy& pnt)
{
    os << "X: " << setw(10) << left << pnt.x_coordinate_ << " Y: " << setw(10) << left << pnt.y_coordinate_;
    return os;
}

Note that I fixed another error where you used size_t instead of n as an argument to the constructor for your vector. As pointed out in the comments, that's actually incorrect to begin with because of the way you're populating the vector. Instead, I changed it to reserve the required size before pushing elements.

Also you're missing some headers and using loads of others. All you really need is:

#include <iostream>
#include <iomanip>
#include <vector>
#include <random>
  • Related