Nee, de C++ parser regels maken al assumpties over de aard van een identifier. Een type-name heeft een andere terminal dan een nontype. Typisch wordt type informatie geprocessed door de parser (adhv typedef, class, struct, enum en namespace declarations) teruggekoppeld naar de lexer. Dit is ook de hele reden waarom 'typename' zo belangrijk is in templates op dependent names. Zonder 'typename' gaat de parser er vanuit dat het geen type is en volgt hij dus ook niet die productieregels.
Bovendien heeft ADL juist niets te maken met het onderscheid tussen type en functie. Het gaat louter om de names uit verschillende namespaces welke gebruikt moeten worden in de uiteindelijke overload resolution. En die neemt uiteraard alleen de funtie-declaraties uit die geassocieerde namespaces mee. Daarom is deze code ook correct:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
| namespace test
{
struct foo { };
void bar(foo) { }
struct bar { };
}
int main()
{
test::foo f;
bar(f);
} |
De struct 'test::bar' hide eigenlijk de functie 'test::bar'. Toch zijn er geen conflicten, want ADL pakt alleen de functiedeclaraties uit 'test'. Overigens, als je de definities van beide bars omdraait dan is ook duidelijk te zien dat de parser info heeft over type informatie - je krijgt dan een syntax error op de plek van de functiedefinitie, omdat een type (void) gevolgd door een type (bar) niet geldig is.
Ook wordt ADL niet eens toegepast als er een class method wordt gevonden in de huidige scope, wat destemeer aangeeft dat type vs nontype resolutie dan al heeft plaatsgevonden.
[
Voor 62% gewijzigd door
.oisyn op 04-02-2011 13:06
]