Member initializer does not name a non-static data member - c++

I am new to C++ and trying to get an open source C++ project to compile in x-code. The last two lines of this code:
template<typename T>
struct TVector3 : public TVector2<T> {
T z;
TVector3(T _x = 0.0, T _y = 0.0, T _z = 0.0)
: TVector2(_x, _y), z(_z)
are throwing the error: Member initializer does not name a non-static data member
Based on (member initializer does not name a non-static data member or base class), I tried changing the code to this:
template<typename T>
struct TVector3 : public TVector2<T> {
T z;
TVector3(T _x = 0.0, T _y = 0.0, T _z = 0.0)
: TVector2(_x, _y)
{ z(_z);}
But I am getting the same error. Here is the code for the super-class, Vector2. How can I resolve this error?
struct TVector2 {
T x, y;
TVector2(T _x = 0.0, T _y = 0.0)
: x(_x), y(_y)
{}
double Length() const {
return sqrt(static_cast<double>(x*x + y*y));
}
double Norm();
TVector2<T>& operator*=(T f) {
x *= f;
y *= f;
return *this;
}
TVector2<T>& operator+=(const TVector2<T>& v) {
x += v.x;
y += v.y;
return *this;
}
TVector2<T>& operator-=(const TVector2<T>& v) {
x -= v.x;
y -= v.y;
return *this;
}
};

Inside a class template, only its own name is injected for use without template arguments. You need this:
template<typename T>
struct TVector3 : public TVector2<T> {
T z;
TVector3(T _x = 0.0, T _y = 0.0, T _z = 0.0)
: TVector2<T>(_x, _y), z(_z)

Related

Conversion from class to identical class with different template types

I have the simple class "vec2". I would like this class to be able to store doubles and double references in the class template, or even int and int references. Here is the desired behavior-
vec2<double> base(5, 5); //normal vec2
vec2<double&> reference(base.x, base.y); //vec2 reference to vec2 "base"
vec2<double> third;
base.x++; //base.x equals 6, this also changes reference.x to 6;
third = reference; //conversion between vec2<double> and vec2<double&>
I would also like modifying a reference instance of vec2 to be impossible, except by changing the variables it is referencing- so the following code would give a compiler error
vec2<double&> reference(base.x, base.y); //vec2 reference to vec2 "base"
reference.x = 5; //undesired behaviour
Is there a way to make the members x and y public when dealing with non-reference class types, but private when the class type is a reference? This would require methods specific to when it is a reference that will return the values of x and y. In the reference version it would also need to not have the overloaded operator methods that can affect the references. I slightly understand template specialization, but not enough to actually implement it.
Anyways, the main point of this is to find out how to take a class of type vec2<double>, and convert it to a class of type vec2<double&>.
Or, conversely, take a class of type vec2<double&>, and convert it to a class of type vec2<double>.
Here is my simple vec2 class-
template <class T> class vec2{
public:
vec2(){
x = 0;
y = 0;
}
vec2(T X, T Y){
x = X;
y = Y;
}
void normalize(){ //this function should inaccesable to any "reference version" of vec2
*this /= magnitude();
}
void rotate(double radians, vec2 center){ //this should also be inaccesable to reference versions
vec2 ogPts = *this -= center;
x = ogPts.x*cos(radians) - ogPts.y*sin(radians);
y = ogPts.y*cos(radians) + ogPts.x*sin(radians);
*this += center;
}
double magnitude() const{
return sqrt(x * x + y * y); //this should be available to both
}
T x;
T y;
vec2 operator+(const vec2 &v) const{ //available to both
return vec2(x+v.x, y+v.y);
}
vec2 operator-(const vec2 &v) const{ //available to both
return vec2(x-v.x, y-v.y);
}
vec2 operator*(const vec2 &v) const{ //available to both
return vec2(x*v.x, y*v.y);
}
vec2 operator*(T v) const{ //available to both, but should work even if v is not a reference variable and T is a reference
return vec2(x*v, y*v);
}
vec2 operator/(T v) const{ //available to both, but should work even if v is not a reference variable and T is a reference
return vec2(x/v, y/v);
}
vec2 operator+=(const vec2 &v){ //inaccesable to reference versions of the class
x += v.x;
y += v.y;
return *this;
}
vec2 operator-=(const vec2 &v){ //inaccesable to reference versions
x -= v.x;
y -= v.y;
return *this;
}
vec2 operator*=(const vec2 &v){ //inaccesable to reference versions
x *= v.x;
y *= v.y;
return *this;
}
vec2 operator*=(T v){ //inaccesable to reference versions
x *= v;
y *= v;
return *this;
}
vec2 operator/=(T v){ //inaccesable to reference versions
x /= v;
y /= v;
return *this;
}
bool operator==(const vec2 &v) const{ //this should be available to both
return (v.x == x && v.y == y);
}
bool operator!=(const vec2 &v) const{ //this should be available to both
return (v.x != x || v.y != y);
}
};
Any help is much appreciated! I haven't worked with templates much, in fact, I just started yesterday! Thanks in advance for your time!
I did a bit more research, and managed to learn a lot on template specialization. Here is the functioning vec2 class which implements everything I wanted, plus a "perpindiculate" function and a "swap" function-
template <class T> class vec2{
public:
vec2(){
x = 0;
y = 0;
}
vec2(T X, T Y){
x = X;
y = Y;
}
operator vec2<T&>(){
return vec2<T&>(x, y);
}
void swap(){
std::swap(x, y);
}
void perpindiculate(){
std::swap(x, y);
y = -y;
}
void normalize(){
*this /= magnitude();
}
void rotate(double radians, vec2 center){
vec2 ogPts = *this -= center;
x = ogPts.x*cos(radians) - ogPts.y*sin(radians);
y = ogPts.y*cos(radians) + ogPts.x*sin(radians);
*this += center;
}
double magnitude() const{
return sqrt(x * x + y * y);
}
vec2 operator+(const vec2 &v) const{
return vec2(x+v.x, y+v.y);
}
vec2 operator-(const vec2 &v) const{
return vec2(x-v.x, y-v.y);
}
vec2 operator*(const vec2 &v) const{
return vec2(x*v.x, y*v.y);
}
vec2 operator*(T v) const{
return vec2(x*v, y*v);
}
vec2 operator/(T v) const{
return vec2(x/v, y/v);
}
vec2 operator+=(const vec2 &v){
x += v.x;
y += v.y;
return *this;
}
vec2 operator-=(const vec2 &v){
x -= v.x;
y -= v.y;
return *this;
}
vec2 operator*=(const vec2 &v){
x *= v.x;
y *= v.y;
return *this;
}
vec2 operator*=(T v){
x *= v;
y *= v;
return *this;
}
vec2 operator/=(T v){
x /= v;
y /= v;
return *this;
}
bool operator==(const vec2 &v) const{
return (v.x == x && v.y == y);
}
bool operator!=(const vec2 &v) const{
return (v.x != x || v.y != y);
}
T x;
T y;
};
template<class T>
class vec2<T&>{
public:
vec2(T& X, T& Y) : x{X}, y{Y} {}
operator vec2<T>(){
return vec2<T>(x, y);
}
vec2<T> swap() const{
return vec2<T>(y, x);
}
vec2<T> perpindiculate() const{
return vec2<T>(-y, x);
}
vec2<T> normalize() const{
return *this / magnitude();
}
vec2<T> rotate(double radians, vec2 center) const{
return vec2<T>(x*cos(radians) - y*sin(radians), y*cos(radians) + x*sin(radians));
}
double magnitude() const{
return sqrt(x * x + y * y);
}
vec2 operator+(const vec2 &v) const{
return vec2(x+v.x, y+v.y);
}
vec2 operator-(const vec2 &v) const{
return vec2(x-v.x, y-v.y);
}
vec2 operator*(const vec2 &v) const{
return vec2(x*v.x, y*v.y);
}
vec2 operator*(T& v) const{
return vec2(x*v, y*v);
}
vec2 operator/(T& v) const{
return vec2(x/v, y/v);
}
bool operator==(const vec2 &v) const{
return (v.x == x && v.y == y);
}
bool operator!=(const vec2 &v) const{
return (v.x != x || v.y != y);
}
T getx(){
return x;
}
T gety(){
return y;
}
private:
T& x;
T& y;
};
Here is an example of it working-
double x = 5; //create future reference variables
double y = 3;
vec2<double&> vecref(x, y); //create vec2 referring to x and y
x = 7; //change x and y values, also changing vecref's values as well
y = 8;
vec2<double> vecOffRef = vecref; //conversion from a reference vec to a normal one
vec2<double&> vecOffRefref = vecOffRef; //conversion from a normal vec to a reference one
vecOffRef.normalize(); //normalize vec, also normalizing vecOffRefref
/* x equals 7, y = 8
vecRef equals (7, 8)
vecOffRef equals (0.6585, .7525)
vecOffRefRef equals (0.6585, .7525) */
A simplified version. By making the fields private, they can't be modified. I didn't try implementing all the operator= methods, but your code should work.
I'm not quite sure where your confusion is. A scan didn't see any problems, except I'd make the fields private so no one can touch them, and add accessor methods instead.
#include <iostream>
using namespace std;
template <class T>
class MyClass {
private:
T x;
T y;
public:
MyClass(T _x, T _y) : x(_x), y(_y) {}
T getX() const { return x; }
T getY() const { return y; }
};
int main(int, char **) {
double x {1.0};
double y {2.5};
MyClass<double> withDouble(x, y);
MyClass<double &> withRef{x, y};
cout << "withDouble: " << withDouble.getX() << ", " << withDouble.getY() << endl;
cout << "withRef: " << withRef.getX() << ", " << withRef.getY() << endl;
x = 3.9;
y = 5.4;
cout << "withRef: " << withRef.getX() << ", " << withRef.getY() << endl;
}

C++ function that can take integer or float or double or any other castable to float

I am trying to implement a Vector3 struct in C++. I am overloading the "*" operator for handling multiplication with the scalar values. So it will work like this:
v1 = Vector3(1.0f, 1.0f, 1.0f);
v2 = 2*v1;
v3 = 2.4f*v1;
v4 = 2.4*v1;
All 3 operations will return a Vector3 instance. However, I don't want to implement 3 functions for this purpose.
Vector3 operator * (int& const val) {
float _val = static_cast<float> (val);
return Vector3(x * _val, y * _val, z * _val);
}
Vector3 operator * (double& const val) {
float _val = static_cast<float> (val);
return Vector3(x * _val, y * _val, z * _val);
}
Vector3 operator * (float& const val) {
return Vector3(x * val, y * val, z * val);
}
Is there a better way of doing this with one function?
Since you are casting all of the types to float again, you don't need that.
If you defined your function to accept a float, then passed an int or any convertible type, it would be cast to float automatically. The following code shows that
#include <typeinfo>
#include <iostream>
struct Vector3
{
Vector3(float x, float y, float z): x{x}, y{y}, z{z}{}
float x, y, z;
Vector3 operator*(float val)const{
return Vector3{val * x,val * y,val * z};
}
};
int main(){
Vector3 v1{1,2,3};
auto v2 = v1*2;
std::cout << typeid(v2.x).name();
}
Live
If you want to use the multiplication in reverse order
#include <typeinfo>
#include <iostream>
struct Vector3
{
Vector3(float x, float y, float z): x{x}, y{y}, z{z}{}
float x, y, z;
};
Vector3 operator*(float val, const Vector3& v){
return Vector3{val * v.x,val * v.y,val * v.z};
}
int main(){
Vector3 v1{1,2,3};
auto v2 = 2*v1;
std::cout << typeid(v2.x).name();
}
I used public members for simplicity. u may want to use private ones with setters and getters.
If you really must use reference parameters and the float data type internally, and you wish to avoid compiler warnings about implicit conversions, then you can use a templated operator function (note also the modified position of the const qualifier):
template<typename T>
Vector3 operator * (const T& val)
{
float mul = static_cast<float>(val); // Change this to any specific conversion/cast you want
return Vector3(x * mul, y * mul, z * mul);
}
You will also need to use a Vector3 object as the first operand of the * operator:
int main()
{
Vector3 v1 = Vector3(1.0f, 1.0f, 1.0f);
// Vector3 v2 = 2 * v1;
// Vector3 v3 = 2.4f * v1; // These won't work!
// Vector3 v4 = 2.4 * v1;
Vector3 v2 = v1 * 2;
Vector3 v3 = v1 * 2.4f; // But these will
Vector3 v4 = v1 * 2.4;
return 0;
}
EDIT: If you want a 'commutative' operator (that is, one in which you could use the scalar operand in either position), then you can declare a friend operator that takes two arguments (the constant and a class reference):
template<typename T>
friend Vector3 operator * (const T& val, const Vector3& vec)
{
float mul = static_cast<float>(val); // Change this to any specific conversion/cast you want
return Vector3(vec.x * mul, vec.y * mul, vec.z * mul);
}
As I see, it's enough to define/declare variant with double and it will work with floats and integers as well.
Here is compilable example (just test & demonstration):
class Vector3 {
public:
Vector3(double x, double y, double z): x(x), y(y), z(z) { }
Vector3 operator * (double val) {
return Vector3(x * val,
y * val,
z * val);
}
private:
double x { 0 };
double y { 0 };
double z { 0 };
};
int main()
{
int a = 1;
float b = 2.1;
double c = 3.5;
Vector3 vec1(1, 2.1f, 3);
Vector3 vec2(a, b, c);
auto vec3 = vec1 * a;
auto vec4 = vec1 * b;
auto vec5 = vec1 * c;
return 0;
}

Making your classes work with floats as well as with integers (analyzing a piece of code) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm analyzing a piece of code and I came across this
class X
{
//content
};
typedef X<float> X;
Can someone points me to something closer to the source of what this (using
<type> to basically make a second class working with second type) is called, how does it work or in what cases we use this so I can continue the search. (In my case it was used as a class defining a 3-dimensional vector.)
this is the entire code:
template<typename T>
class Vec3
{
public:
T x, y, z;
Vec3() : x(T(0)), y(T(0)), z(T(0)) {}
Vec3(T xx) : x(xx), y(xx), z(xx) {}
Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {}
Vec3& normalize()
{
T nor2 = length2();
if (nor2 > 0) {
T invNor = 1 / sqrt(nor2);
x *= invNor, y *= invNor, z *= invNor;
}
return *this;
}
Vec3<T> operator * (const T &f) const { return Vec3<T>(x * f, y * f, z * f); }
Vec3<T> operator * (const Vec3<T> &v) const { return Vec3<T>(x * v.x, y * v.y, z * v.z); }
T dot(const Vec3<T> &v) const { return x * v.x + y * v.y + z * v.z; }
Vec3<T> operator - (const Vec3<T> &v) const { return Vec3<T>(x - v.x, y - v.y, z - v.z); }
Vec3<T> operator + (const Vec3<T> &v) const { return Vec3<T>(x + v.x, y + v.y, z + v.z); }
Vec3<T>& operator += (const Vec3<T> &v) { x += v.x, y += v.y, z += v.z; return *this; }
Vec3<T>& operator *= (const Vec3<T> &v) { x *= v.x, y *= v.y, z *= v.z; return *this; }
Vec3<T> operator - () const { return Vec3<T>(-x, -y, -z); }
T length2() const { return x * x + y * y + z * z; }
T length() const { return sqrt(length2()); }
friend std::ostream & operator << (std::ostream &os, const Vec3<T> &v)
{
os << "[" << v.x << " " << v.y << " " << v.z << "]";
return os;
}
};
typedef Vec3<float> Vec3f;
You have probably missed some related piece of code appearing before class X:
template <typename T> // <<<<<<<<<<<<<<<<<<<<<<
class X
{
//content
};
Can someone points me to something closer to the source of what this is called,
That's called a class template.
how does it work
The code provided in the class template definition will be instantiated for various types as provided by
typedef X<float> X;
or
typedef X<int> Y;

argument list for class template Vec2 is missing

I am defining a Vec2 class with a friend functions. I am getting the error: argument list for class template Vec2 is missing for the friend function: friend Vec2 operator * (const T &r, const Vec2 &v).
template<typename T>
class Vec2
{
public:
Vec2() : x(0), y(0) {}
Vec2(T xx) : x(xx), y(xx) {}
Vec2(T xx, T yy) : x(xx), y(yy) {}
Vec2 operator + (const Vec2 &v) const
{ return Vec2(x + v.x, y + v.y); }
Vec2 operator / (const T &r) const
{ return Vec2(x / r, y / r); }
Vec2 operator * (const T &r) const
{ return Vec2(x * r, y * r); }
Vec2& operator /= (const T &r)
{ x /= r, y /= r; return *this; }
Vec2& operator *= (const T &r)
{ x *= r, y *= r; return *this; }
friend std::ostream& operator << (std::ostream &s, const Vec2<T> &v)
{
return s << '[' << v.x << ' ' << v.y << ']';
}
friend Vec2 operator * (const T &r, const Vec2<T> &v)
{ return Vec2(v.x * r, v.y * r); }
T x, y;
};

Overloading * operator gives no match error

Hi I am trying to create a ray tracer that renders a polygonized, triangle-based model.
I have a point 3D struct in point3d.h that holds x,y, and z coordinates.
#ifndef __POINT3D_H__
#define __POINT3D_H__
#include <iostream>
using namespace std;
struct Point3D
{
double x;
double y;
double z;
Point3D() : x(0.0), y(0.0), z(0.0) {}
Point3D(const double & nx, const double & ny, const double & nz) : x(nx), y(ny), z(nz) {}
Point3D operator+(const Point3D & rhs) const {
return Point3D(x + rhs.x, y + rhs.y, z + rhs.z); }
Point3D operator-(const Point3D & rhs) const {
return Point3D(x - rhs.x, y - rhs.y, z - rhs.z); }
Point3D operator*(double val) const {
return Point3D(x * val, y * val, z * val); }
Point3D operator/(double val) const {
return Point3D(x / val, y / val, z / val); }
Point3D operator+=(const Point3D & rhs) {
x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
Point3D operator-=(const Point3D & rhs) {
x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
Point3D operator*=(double val) {
x *= val; y *= val; z *= val; return *this; }
Point3D operator/=(double val) {
x /= val; y /= val; z /= val; return *this; }
void print() {
cout << '(' << x << ',' << y << ',' << z << ')';
}
};
#endif
Here is where I try to use the * operator to multiple two Point3Ds together
Point3D phong(Point3D mColor, Point3D lColor, Point3D L, Point3D N, Point3D R, Point3D V)
{
Point3D k(1.0, 1.0, 1.0);
Point3D ambient = mColor * k.x;
Point3D diffuse_angle = ((N * L) / (length(N) * length(L)));
Point3D diffuse = lColor * k.y * diffuse_angle;
Point3D specular_angle = ((R * V) / (length(R) * length(V)));
double specular_x = pow(specular_angle.x, 100.0);
double specular_y = pow(specular_angle.y, 100.0);
double specular_z = pow(specular_angle.z, 100.0);
Point3D specular_power(specular_x, specular_y, specular_z);
Point3D specular = lColor * k.z * specular_power;
return ambient + (lColor * (diffuse + specular));
}
When I try to multiple two Point3D's together, I am getting a no match error.
Here is where the code fails. I feel like it is a simple mistake but I cannot figure it out. I am including the Point3d header file as follows: #include "point3d.h".
Point3D operator*(double val) const
You have just this version, Point3D * double and nothing else, but you are trying to use this operator for Point3D * Point3D. Point3D is not implicitly constructible from double, so this is why you have compilation error.
Point3D operator*(double val) const {
This is for multiplication Point3D * double. And by
N * L
you are trying to do Point3D * Point3D.
You can rectify this either by providing proper operator* for your class OR provide a conversion from double to your class through single argument constructor. Although I prefer former.
You should need a function like this
Point3D operator *(Point3D &temp) const {
}
Since you don't have function to multiply two 3d points you are getting errors.Try adding this function.
You need a function for the operation Point3D * Point3D, which can't be adapted for the call of Point3D::operator*(double val). Such as:
Point3D operator*(const Point3D & rhs) const {
return Point3D(x * rhs.x, y * rhs.y, z * rhs.z); }