0

I created a virtual bool function in a class (material) and made a super class (diffuse) that defines the body of the function (scatter()).

The issue is in the parameters of this function, because they give an error: syntax error: missing ',' before '&'. I have no idea why this is happening, because I used the same exact code in another project that worked.

#ifndef MATERIAL_H
#define MATERIAL_H

#include "ray.h"
#include "vec3.h"
#include "hittable_list.h"
#include "hittable.h"

class material {
public:

    virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const = 0; //problem
//Error C4430   missing type specifier-int assumed. 
//Error C2143   syntax error: missing ',' before '&'    



};

class diffuse : public material {
public:
    diffuse(const color& a) : albedo(a) {}

    virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const {

        vec3 scatter_direction = rec.normal + vec3::random_unit_vector();
        scattered = ray(rec.p, scatter_direction);
        attenuation = albedo;
        return true;

    }

public:
    color albedo;
};


#endif

ray.h

#ifndef RAY_H
#define RAY_H

#include "vec3.h"

class ray {
public:
    ray() {}
    ray(const point3& origin, const vec3& direction, double time = 0.0)
        : orig(origin), dir(direction), tm(time)
    {}

    point3 origin() const { return orig; }
    vec3 direction() const { return dir; }
    double time() const { return tm; }

    point3 at(double t) const {
        return orig + t * dir;
    }

public:
    point3 orig;
    vec3 dir;
    double tm;
};

#endif

hittable.h

#ifndef HITTABLE_H
#define HITTABLE_H

#include "ray.h"
#include "material.h"

class material;
struct hit_record {
    point3 p;
    vec3 normal;
    shared_ptr<material> mat_ptr;
};

class hittable {
public:
    virtual bool hit(const ray& r, hit_record& rec) const = 0;
};

#endif

hittable_list.h


#ifndef HITTABLE_LIST_H
#define HITTABLE_LIST_H

#include "hittable.h"

#include <memory>
#include <vector>

using std::shared_ptr;
using std::make_shared;

class hittable_list : public hittable {
public:
    hittable_list() {}
    hittable_list(shared_ptr<hittable> object) { add(object); }

    void clear() { objects.clear(); }
    void add(shared_ptr<hittable> object) { objects.push_back(object); }

    virtual bool hit(const ray& r, hit_record& rec) const;

public:
    std::vector<shared_ptr<hittable>> objects;
};

bool hittable_list::hit(const ray& r, hit_record& rec) const {
    bool hit_anything = false;


    for (const auto& object : objects) {
        if (object->hit(r, rec)) {
            hit_anything = true;
        }
    }

    return hit_anything;
}
#endif

vec3.h

#pragma once

#ifndef VEC3_H
#define VEC3_H

#include <cmath>
#include <iostream>
#include <algorithm>
#include "mathing.h"

using std::sqrt;

class vec3 {
public:
    vec3() : e{ 0,0,0 } {}
    vec3(double e0, double e1, double e2) : e{ e0, e1, e2 } {}

    double x() const { return e[0]; }
    double y() const { return e[1]; }
    double z() const { return e[2]; }

    vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
    double operator[](int i) const { return e[i]; }
    double& operator[](int i) { return e[i]; }

    vec3& operator+=(const vec3 &v) {
        e[0] += v.e[0];
        e[1] += v.e[1];
        e[2] += v.e[2];
        return *this;
    }

    vec3& operator*=(const double t) {
        e[0] *= t;
        e[1] *= t;
        e[2] *= t;
        return *this;
    }

    vec3& operator/=(const double t) {
        return *this *= 1 / t;
    }

    double length() const {
        return sqrt(length_squared());
    }

    double length_squared() const {
        return e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
    }

public:
    double e[3];

    inline static vec3 random() {
        return vec3(random_double(), random_double(), random_double());
    }

    inline static vec3 random(double min, double max) {
        return vec3(random_double(min, max), random_double(min, max), random_double(min, max));
    }
    inline static vec3 random_unit_vector() {
        auto a = random_double(0, 2 * pi);
        auto z = random_double(-1, 1);
        auto r = sqrt(1 - z * z);
        return vec3(r*cos(a), r*sin(a), z);
    }

};

inline std::ostream& operator<<(std::ostream &out, const vec3 &v) {
    return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2];
}

inline vec3 operator+(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]);
}

inline vec3 operator-(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]);
}

inline vec3 operator*(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]);
}

inline vec3 operator*(double t, const vec3 &v) {
    return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}

inline vec3 operator*(const vec3 &v, double t) {
    return t * v;
}

inline vec3 operator/(vec3 v, double t) {
    return (1 / t) * v;
}

inline double dot(const vec3 &u, const vec3 &v) {
    return u.e[0] * v.e[0]
        + u.e[1] * v.e[1]
        + u.e[2] * v.e[2];
}

inline vec3 cross(const vec3 &u, const vec3 &v) {
    return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1],
        u.e[2] * v.e[0] - u.e[0] * v.e[2],
        u.e[0] * v.e[1] - u.e[1] * v.e[0]);
}

inline vec3 unit_vector(vec3 v) {
    return v / v.length();
}

inline static vec3 random_in_unit_sphere() {
    while (true) {
        auto p = vec3::random(0, 1);
        if (p.length_squared() >= 1) continue;
        return p;
    }
}

inline static vec3 random_in_hemisphere(const vec3& normal) {
    vec3 in_unit_sphere = random_in_unit_sphere();
    if (dot(in_unit_sphere, normal) > 0.0) // In the same hemisphere as the normal
        return in_unit_sphere;
    else
        return -in_unit_sphere;
}

inline static vec3 reflect(const vec3& v, const vec3& n) {
    return v - 2 * dot(v, n)*n;
}

vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat) {
    auto cos_theta = dot(-uv, n);
    vec3 r_out_parallel = etai_over_etat * (uv + cos_theta * n);
    vec3 r_out_perp = -sqrt(1.0 - r_out_parallel.length_squared()) * n;
    return r_out_parallel + r_out_perp;
}
double schlick(double cosine, double ref_idx) {
    auto r0 = (1 - ref_idx) / (1 + ref_idx);
    r0 = r0 * r0;
    return r0 + (1 - r0)*pow((1 - cosine), 5);
}
vec3 random_in_unit_disk() {
    while (true) {
        auto p = vec3(random_double(-1, 1), random_double(-1, 1), 0);
        if (p.length_squared() >= 1) continue;
        return p;
    }
}


// Type aliases for vec3
using point3 = vec3;   // 3D point
using color = vec3;    // RGB color

#endif


  • Please provide the exact code and exact error message. – Dmitry Kuzminov Jun 13 '20 at 01:19
  • That is a **LOT** of code for a simple syntax error. The version of this question that got deleted was clearer (albeit incomplete -- you've swung too far in the other direction). – JaMiT Jun 13 '20 at 01:26
  • ARE the diagnostics you've described the FIRST or the LAST issued by the compiler? The FIRST diagnostics from the compiler are what you need to look at. The LAST will be the error message at the bottom of the screen/window. I suspect you're looking at the LAST. The order in which you look at error messages, and try to fix their cause, matters. When there is a lot of errors in the code, the compiler gets progressively more confused, and the error messages become less relatable to the code.The LAST error message is therefore often not helpful in identifying the actual problem – Peter Jun 13 '20 at 01:50

2 Answers2

1

Quick correction, diffuse is a subclass of material, not a super class :-)

As for the issue at hand, it looks there might be a type error (c++ will assume int for unknown types). It looks like . Your error message should contain a line and column number which would help point which type is not resolving. All other errors after the first error can generally be ignored because the compiler starts guessing and may get really confused about where it is in the parse.

The type issue is caused by a circular reference between hittable.h and material.h. To fix this you can remove the #include material.h from hittable.h since you have the forward declaration class material.

ThisCompSciGuy
  • 176
  • 2
  • 11
0

One possible reason could be that you include #include "hittable.h" from material.h and #include "material.h" from hittable.h. In general that is not an issue, bit you need to be careful and provide forward declarations in both cases. There is no forward declaration in material.h though.

One more reason to suspect this issue that you mix include guards and #pragma once - please revise your code, there may be other issues of circular dependencies.

Dmitry Kuzminov
  • 6,180
  • 6
  • 18
  • 40
  • What happens when the `#include "material.h"` is removed from _hittable.h_, @mr-anonymous? The forwards declaration is all it needs, no? – Neil Gatenby Jun 13 '20 at 01:32
  • 1
    @NeilGatenby, we need to see the .cpp files to understand what would happen. Anyway, proper coding style covers the policies of include guards, includes sorting, forward declarations, etc: refactoring this code should be very useful. – Dmitry Kuzminov Jun 13 '20 at 01:36
  • I removed the `#include "material.h" `from the hittable header. That seemed to work because it was making a circular reference since I made a forward reference for the material class in the hittable – Mr Anonymous Jun 13 '20 at 03:11