I have written a simple worksheet program to convert between cartesian coordinates and polar coordinates. When compiled, an error is displayed.
Code:
#include <iostream>
#include <cmath>
#include <iomanip>
#define PI 3.14159
struct Polar;
struct Vector2;
struct Polar{
double r, theta;
Vector2 toCartesian(){
return {r*cos(theta*PI/180), r*sin(theta*PI/180)};
}
};
struct Vector2{
double x,y;
Polar toPolar(){
return {sqrt(x*x + y*y), atan(y/x)};
}
};
int main(){
std::cout << "Enter Polar coordinates in form of R theta to convert to cartesian: ";
Polar P;
std::cin >> P.r >> P.theta;
Vector2 Pcord;
Pcord = P.toCartesian();
std::cout << std::fixed << std::setprecision(3) << "(x,y) = " << Pcord.x << " " << Pcord.y;
std::cin.get();
return 0;
}
Error message:
exe.cpp: In member function 'Vector2 Polar::toCartesian()':
exe.cpp:14:26: error: return type 'struct Vector2' is incomplete
Vector2 toCartesian(){
^
exe.cpp: In function 'int main()':
exe.cpp:34:27: error: no match for 'operator=' (operand types are 'Vector2' and 'void')
Pcord = P.toCartesian();
^
exe.cpp:19:8: note: candidate: constexpr Vector2& Vector2::operator=(const Vector2&)
struct Vector2{
^~~~~~~
exe.cpp:19:8: note: no known conversion for argument 1 from 'void' to 'const Vector2&'
exe.cpp:19:8: note: candidate: constexpr Vector2& Vector2::operator=(Vector2&&)
exe.cpp:19:8: note: no known conversion for argument 1 from 'void' to 'Vector2&&'*
What is the issue here? At first, I thought this was because the compiler didn't know struct Vector2
exists when going through struct Polar
, similar to calling a function declared below from another function, so I used a forward declaration, but the issue is not resolved.
A forward declaration merely tells the compiler that a type exists, but not what that type looks like, so the compiler doesn't known what is needed to create instances of that type.
You are trying to create a Vector2
instance before the compiler knows what Vector2
contains. That is why the error message says Vector2
is an incomplete type.
To accomplish what you are trying to do, you must separate the declaration and definition of Polar::toCartesian()
so that you can fully define Vector2
before you can then create an instance of it, eg:
#include <iostream>
#include <cmath>
#include <iomanip>
#define PI 3.14159
struct Vector2;
struct Polar{
double r, theta;
Vector2 toCartesian();
};
struct Vector2{
double x,y;
Polar toPolar(){
return {sqrt(x*x + y*y), atan(y/x)};
}
};
Vector2 Polar::toCartesian(){
return {r*cos(theta*PI/180), r*sin(theta*PI/180)};
}
int main(){
std::cout << "Enter Polar coordinates in form of R theta to convert to cartesian: ";
Polar P;
std::cin >> P.r >> P.theta;
Vector2 Pcord;
Pcord = P.toCartesian();
std::cout << std::fixed << std::setprecision(3) << "(x,y) = " << Pcord.x << " " << Pcord.y;
std::cin.get();
return 0;
}