Skip to content

Instantly share code, notes, and snippets.

@rofirrim
Last active December 16, 2015 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rofirrim/5441275 to your computer and use it in GitHub Desktop.
Save rofirrim/5441275 to your computer and use it in GitHub Desktop.
Another C++ rant
template <typename T>
struct f // This is ::f
{
};
namespace B
{
template <typename T>
struct f // This is B::f
{
void g();
};
}
struct A : B::f<int> // This ::A
{
};
void g(A& b)
{
/*
(See C++ 2003 §3.4.5 [basic.lookup.classref])
The standard says, that when after a . (or ->) we find an "identifier"
("f" in this example) followed by a '<', we first lookup in the class of
the postfix expression (the postfix expression here is "b"). If the name
found is a template class name (we find B::f which is a template class
name), we also have to check the context of the whole expression (so we
find the global ::f).
The standard says that in this case they should be the same template (they
are not in this example).
Truth is that g++ just ignores this _plain stupid_ rule and clang emits a warning.
Both compilers assume the context of the postfix (B::f<int>) prevails. This is
what any sensible human would assume first.
C++ sucks.
*/
b.f<int>::g();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment