On Saturday, 20 October 2018 13:38:40 UTC+3, Paul wrote:
> Below code (after CODE BEGINS marker) compiles and runs successfully with gcc but
> I would have expected an error.
> See the part between the asterisks. Here we have an operation
> returning AndSpecification<T> before AndSpecification<T> has been
> fully defined. So I would expect the compiler to complain because
> it doesn't know (at this stage) that first and second are members
> of AndSpecification<T>
> I don't know why the compiler accepts the code between the asterisks.
> I would have said it's an error because AndSpecification<T> has not
> been fully defined so we don't know what return {first, second} means.
>
> Many thanks for your help,
With templates it does not matter so much where it was declared or
where it was defined. More important is that it is defined at place
where it is instantiated. Template of operator&& is instantiated
where it is called. If it is called nowhere then even syntax errors
in its definition may compile. Standard says ill-formed, no diagnostics
required.
Similar are references or pointers to some type. These can be
declared to incomplete type. Complete type is required where such
reference is used or pointer is dereferenced.
That makes programming in C++ not linear process but also it gives
plenty of ways to break out of circular references between types
and functions without sacrificing any type-safety.