In the following snippet of C++ code, I have declared a function type using the incomplete type syntax inside a namespace s
, but the inner struct unknown_type
have namespace scope and so the full qualified name of the argument is taken as ::s::unknown_type
.
So this works:
namespace s {
using callback = void(struct unknown_type);
struct unknown_type {};
}
void f(s::unknown_type) {}
int main()
{
s::callback* cb = f;
(void)cb;
return 0;
}
but this doesn't:
namespace s {
using callback = void(struct unknown_type);
}
struct unknown_type {};
void f(unknown_type) {}
int main()
{
s::callback* cb = f;
(void)cb;
return 0;
}
I know that I can just properly forward declare the type as usual, but I'm curious about this syntax. I have tried with using callback = void(struct ::unknown_typee)
but it doesn't work. Is there a way to forward declare a type using the incomplete type syntax specifying the right expected namespace?
Is there a way to forward declare a type using the incomplete type syntax specifying the right expected namespace?
Simply put, no, there is no way. The way this is specified in the latest C++ standard (c++23) is probably clearest.
[basic.lookup.elab]
2 If the terminal name of the elaborated-type-specifier is a qualified name, lookup for it is type-only. If the name lookup does not find a previously declared type-name, the elaborated-type-specifier is ill-formed.
Lookup being "type-only" is (very roughly speaking) standard verbiage for doing lookup that should only find types (in other contexts, types may be hidden). Unlike unqualified names, this passage explicitly tells us that if we form an elaborate-type-specifier with a fully qualified name, it must refer to a class whose declaration is already visible at this point.
It is then followed by an (albeit non-normative) example that applies to your question:
[basic.lookup.elab]
3 ...
struct Data { // ... friend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([dcl.type.elab]) friend struct Glob; // OK, refers to (as yet) undeclared Glob at global scope. /* ... */ };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With