-1

I'm fairly new to C and C++. For practice I created Vector structs (Vector2 & Vector3). Now I want one to be dynamically casted to the other.

struct A {
    operator B() const { return B(); }
}

struct B {
    
}

works just fine, but as soon as I add

operator A() const { return A(); }

to struct B it throws all kinds of errors.

I tried Header Files, etc.

Is there a solution that allows this ↓ ?

int main() {
    A a = B();
    B b = A();
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
TK36
  • 332
  • 3
  • 11
  • 1
    The operator overloading is a concept introduced in C++, not C. I don't think if the C tag is appropriate here. – Rohan Bari Mar 18 '21 at 18:47
  • If you have circular references like this, you need a forward declaration of one of the classes. – Barmar Mar 18 '21 at 18:48
  • very related, kind of a dupe: https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes – NathanOliver Mar 18 '21 at 18:50
  • 1
    "all kinds of errors" is pretty vague. Please add the errors to your question. – flowit Mar 18 '21 at 18:51
  • 1
    1. C and C++ are very different languages, even if C is close to being a subset of C++. 2. Please provide the actual code which results in errors, from start to finish. 3. Don't be so hasty in defining comversion operators. First, consider explicit construction of A's from B's. If that's not acceptable - try the constructors `A::A(const B& b)` and `B::B(const A& a)`. – einpoklum Mar 18 '21 at 18:51
  • 1
    @Barmar forward declarations only work for pointers and references, I don't think it would work for the operators in this example, since a return value can't be an incomplete type. – Remy Lebeau Mar 18 '21 at 19:01
  • @TK36 "*`struct A { operator B() const { return B(); } } struct B { }` works just fine*" - no, it doesn't, because you can't use `B` before it has been declared. The compiler doesn't know what `B` is yet when it encounters the declaration of `A::operator B()`, so it fails to compile. – Remy Lebeau Mar 18 '21 at 19:02
  • @RemyLebeau but it does :) I think, the question can actually be reopened, as dupe deals with pointers – SergeyA Mar 18 '21 at 19:19
  • @SergeyA [no, it doesn't work](https://ideone.com/tUZk9T): "*error: expected type-specifier before ‘B’*" – Remy Lebeau Mar 18 '21 at 19:21
  • @RemyLebeau this is because you defined your conversion operator in-line. See my answer. – SergeyA Mar 18 '21 at 19:23
  • @RemyLebeau Return types don't have to be complete. Strange but true. (if you think about it, the size of the return type doesn't matter to the size of the function. Only code calling the function needs to know about the size of the return type) – Yakk - Adam Nevraumont Mar 18 '21 at 19:25
  • C++ permits this sort of circular definition, so there must be something specific about your code that is generating the errors. But you have not shown those errors, so it is impossible to diagnose the cause. Edit the question to provide a [mre] and include the exact text of error messages. Never describe a problem as “all kinds of errors”; always be specific. – Eric Postpischil Mar 18 '21 at 19:28
  • @Yakk-AdamNevraumont and the same would be true for function arguments. – SergeyA Mar 18 '21 at 19:32

1 Answers1

3

You need to forward-declare the structs, and define conversion operators out-of-line, after the types have been fully declared. Here is an example which illustrates the idea:

struct B;

struct A {
    operator B();
};

struct B {
    operator A() { return A(); }
};

inline A::operator B() {
    return B();
}

B foo()
{
    A a;
    return a;
}

To recap, important pieces here are:

  • We first declared struct B without defining it (forward-declaration)
  • We declared conversion operator to B() inside the A class, but didn't define it there
  • Finally, we defined conversion to B() operator out-of-line, after full definition of class B was provided.
  • We were able to define conversion operator to A in-line, because full definition of class A was already provided.
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • thaks for your answer. since I used a Header-File to declare this it worked without the "inline". Now I got it working – TK36 Mar 18 '21 at 19:41