The VirtualC protocol is not very useful in the absence of another struct derived from C, but if there was one it would be used to represent inheritance from C.
Since C is not declared final, there could effectively be another struct we just don't have visibility to but which gets exposed as a C via a C++ pointer/reference somewhere.
Let's make it a bit more complicated, with a diamond:
P
/ \
C D
| |
E /
\ /
F
// C++
struct E : public C { };
struct F : public D, public E { };
// Swift
protocol VirtualE : VirtualC { }
struct E : VirtualE { }
protocol VirtualF : VirtualD, VirtualE { }
struct F : VirtualF { }
let a: [VirtualP] = [C(), D(), E(), F()]
let b: [VirtualC] = [C(), E(), F()]
let c: [VirtualD] = [D(), F()]
let d: [VirtualE] = [E(), F()]
let e: [VirtualF] = [F()]
Each struct is still independent from each other (from Swift's perspective), so you can't put a E somewhere that expects a C, but you can put a E somewhere that expects a VirtualC.
I think I should have called this PolymorphicC instead, as it's not necessarily related to C++'s virtual.
I wonder... can we model C++ reference semantics in a way that supports inheritance using protocols like this? For instance:
// C++
void byCopy(C arg);
void byRef(const C & arg);
// Swift
func byCopy(_ arg: C)
func byRef(_ arg: VirtualC)
Here byCopy can only accept a concrete C and byRef can accept either a C, E, or F. Note that with byCopy you'd get slicing behavior in C++, so even in C++ the function effectively can't deal with derived types, whereas byRef can.