In C++ one cannot overload in one class a member function with ref-qualifier with a member function without ref-qualifier. But at the same time it is possible to inherit one member function from a parent class and overload it in a child class as in the example:
struct A {
void f() {}
//void f() & {} //overload error everywhere
};
struct B : A {
using A::f;
void f() & {} //ok everywhere
};
int main() {
B b;
b.f(); //ok in GCC only
}
Only during the invocation of f, Clang complains that call to member function 'f' is ambiguous. But GCC accepts the program without any error, demo: https://gcc.godbolt.org/z/5zzbWcs97
Which compiler is right here?
GCC is correct to accept this, but the situation changed recently. The current phrasing is that a using-declaration in a class ignores (base-class) declarations that would be ambiguous (in a sense that is more strict than for overload resolution, partly because there is no argument list yet) with other declarations in the class. void() and void() & members are ambiguous in this sense, so b.f finds only B’s f and the call is valid.
In previous (as of this writing, that means “published”) versions of the standard, both functions would be made available because the & distinguished them (in a sense that is even stricter), which would not only render the call ambiguous (as Clang says) but be ill-formed outright because the base- and derived-class functions were checked for overload compatibility which they lack.
Related
The following minimal example compiles fine with MSVC 17 but produces a compilation error on GCC 8.2. Which compiler is right? Is this code correct in C++17?
#include <iostream>
class A
{
public:
A() = default;
protected:
void foo(int x)
{ std::cout << x << std::endl; }
};
class B : private A
{
using Method_t = void (B::*)(int);
using A::foo;
template <Method_t M>
void baz()
{ (this->*M)(42); }
public:
B() = default;
void bar()
{ baz<&B::foo>(); }
};
int main()
{
B().bar();
}
GCC error is:
mwe.cpp:29:20: error: could not convert template argument '&A::foo' from 'void (A::*)(int)' to 'void (B::*)(int)'
This is interesting.
Per the current rules*, it appears that the intent is for foo to remain a member of the base, rather than introducing an actual member of B.
That's despite the fact that overload resolution can now find the member in B:
[namespace.udecl/15]: [Note: For the purpose of forming a set of candidates during overload resolution, the functions that are introduced by a using-declaration into a derived class are treated as though they were members of the derived class ([class.member.lookup]). In particular, the implicit object parameter is treated as if it were a reference to the derived class rather than to the base class ([over.match.funcs]). This has no effect on the type of the function, and in all other respects the function remains a member of the base class. — end note]
That's also despite the fact that, in code, B::bar can refer to that member (i.e. it doesn't have to be spelled A::bar):
[expr.prim.id.qual/2]: A nested-name-specifier that denotes a class, optionally followed by the keyword template ([temp.names]), and then followed by the name of a member of either that class ([class.mem]) or one of its base classes, is a qualified-id; [class.qual] describes name lookup for class members that appear in qualified-ids. The result is the member. The type of the result is the type of the member. [..]
But the actual type of the member is therefore void (A::*)(int).
There is no rule permitting conversion to void (B::*)(int), even one specific to members introduced in this manner (and obviously such a conversion couldn't be valid in general).
Therefore, I believe that Visual Studio is in error.
* I'm citing the current draft, for convenience, but have no reason to believe that this rule has changed recently; both GCC and Clang reject the code in all of C++11, C++14 and C++17.
As an aside, this doesn't actually compile with the latest version of Visual Studio, either:
<source>(29): error C2672: 'B::baz': no matching overloaded function found
<source>(29): error C2893: Failed to specialize function template 'void B::baz(void)'
<source>(21): note: see declaration of 'B::baz'
<source>(29): note: With the following template arguments:
<source>(29): note: 'M=void A::foo(int)'
So, perhaps they've fixed the bug since your version. There is also a compatibility mode in VS that may be to blame.
First, consider this C++ code:
#include <stdio.h>
struct foo_int {
void print(int x) {
printf("int %d\n", x);
}
};
struct foo_str {
void print(const char* x) {
printf("str %s\n", x);
}
};
struct foo : foo_int, foo_str {
//using foo_int::print;
//using foo_str::print;
};
int main() {
foo f;
f.print(123);
f.print("abc");
}
As expected according to the Standard, this fails to compile, because print is considered separately in each base class for the purpose of overload resolution, and thus the calls are ambiguous. This is the case on Clang (4.0), gcc (6.3) and MSVC (17.0) - see godbolt results here.
Now consider the following snippet, the sole difference of which is that we use operator() instead of print:
#include <stdio.h>
struct foo_int {
void operator() (int x) {
printf("int %d\n", x);
}
};
struct foo_str {
void operator() (const char* x) {
printf("str %s\n", x);
}
};
struct foo : foo_int, foo_str {
//using foo_int::operator();
//using foo_str::operator();
};
int main() {
foo f;
f(123);
f("abc");
}
I would expect the results to be identical to the previous case, but it is not the case - while gcc still complains, Clang and MSVC can compile this fine!
Question #1: who is correct in this case? I expect it to be gcc, but the fact that two other unrelated compilers give a consistently different result here makes me wonder whether I'm missing something in the Standard, and things are different for operators when they're not invoked using function syntax.
Also note that if you only uncomment one of the using declarations, but not the other, then all three compilers will fail to compile, because they will only consider the function brought in by using during overload resolution, and thus one of the calls will fail due to type mismatch. Remember this; we'll get back to it later.
Now consider the following code:
#include <stdio.h>
auto print_int = [](int x) {
printf("int %d\n", x);
};
typedef decltype(print_int) foo_int;
auto print_str = [](const char* x) {
printf("str %s\n", x);
};
typedef decltype(print_str) foo_str;
struct foo : foo_int, foo_str {
//using foo_int::operator();
//using foo_str::operator();
foo(): foo_int(print_int), foo_str(print_str) {}
};
int main() {
foo f;
f(123);
f("foo");
}
Again, same as before, except now we don't define operator() explicitly, but instead get it from a lambda type. Again, you'd expect the results to be consistent with the previous snippet; and this is true for the case where both using declarations are commented out, or if both are uncommented. But if you only comment out one but not the other, things are suddenly different again: now only MSVC complains as I would expect it to, while Clang and gcc both think it's fine - and use both inherited members for overload resolution, despite only one being brought in by using!
Question #2: who is correct in this case? Again, I'd expect it to be MSVC, but then why do both Clang and gcc disagree? And, more importantly, why this is different from the previous snippet? I would expect the lambda type to behave exactly the same as a manually defined type with overloaded operator()...
Barry got #1 right. Your #2 hit a corner case: captureless nongeneric lambdas have an implicit conversion to function pointer, which got used in the mismatch case. That is, given
struct foo : foo_int, foo_str {
using foo_int::operator();
//using foo_str::operator();
foo(): foo_int(print_int), foo_str(print_str) {}
} f;
using fptr_str = void(*)(const char*);
f("hello") is equivalent to f.operator fptr_str()("hello"), converting the foo to an pointer-to-function and calling that. If you compile at -O0 you can actually see the call to the conversion function in the assembly before it gets optimized away. Put an init-capture in print_str, and you'll see an error since the implicit conversion goes away.
For more, see [over.call.object].
The rule for name lookup in base classes of a class C only happens if C itself doesn't directly contain the name is [class.member.lookup]/6:
The following steps define the result of merging lookup set S(f,Bi)
into the intermediate S(f,C):
If each of the subobject members of S(f,Bi) is a base class subobject of at least one of the subobject members of S(f,C), or if S(f,Bi) is empty, S(f,C) is unchanged and the merge is complete. Conversely, if each of the subobject members of S(f,C) is a base class subobject of at least one of the subobject members of S(f,Bi), or if S(f,C) is empty, the new S(f,C) is a copy of S(f,Bi).
Otherwise, if the declaration sets of S(f,Bi) and S(f,C) differ, the merge is ambiguous: the new S(f,C) is a lookup set with an invalid declaration set and the union of the subobject sets. In subsequent merges, an invalid declaration set is considered different from any other.
Otherwise, the new S(f,C) is a lookup set with the shared set of declarations and the union of the subobject sets.
If we have two base classes, that each declare the same name, that the derived class does not bring in with a using-declaration, lookup of that name in the derived class would run afoul of that second bullet point and the lookup should fail. All of your examples are basically the same in this regard.
Question #1: who is correct in this case?
gcc is correct. The only difference between print and operator() is the name that we're looking up.
Question #2: who is correct in this case?
This is the same question as #1 - except we have lambdas (which give you unnamed class types with overload operator()) instead of explicit class types. The code should be ill-formed for the same reason. At least for gcc, this is bug 58820.
Your analysis of the first code is incorrect. There is no overload resolution.
The name lookup process occurs wholly before overload resolution. Name lookup determines which scope an id-expression is resolved to.
If a unique scope is found via the name look-up rules, then overload resolution begins: all instances of that name within that scope form the overload set.
But in your code, name lookup fails. The name is not declared in foo, so base classes are searched. If the name is found in more than one immediate base class then the program is ill-formed and the error message describes it as an ambiguous name.
The name lookup rules do not have special cases for overloaded operators. You should find that the code:
f.operator()(123);
fails for the same reason as f.print failed. However, there is another issue in your second code. f(123) is NOT defined as always meaning f.operator()(123);. In fact the definition in C++14 is in [over.call]:
operator() shall be a non-static member function with an arbitrary number of parameters. It can have default arguments. It implements the function call syntax
postfix-expression ( expression-list opt )
where the postfix-expression evaluates to a class object and the possibly empty expression-list matches the parameter list of an operator() member function of the class. Thus, a call x(arg1,...) is interpreted as x.operator()(arg1, ...) for a class object x of type T if T::operator()(T1, T2, T3) exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3.3).
This actually seems an imprecise specification to me so I can understand different compilers coming out with different results. What is T1,T2,T3? Does it mean the types of the arguments? (I suspect not). What are T1,T2,T3 when multiple operator() function exist, only taking one argument?
And what is meant by "if T::operator() exists" anyway? It could perhaps mean any of the following:
operator() is declared in T.
Unqualified lookup of operator() in the scope of T succeeds and performing overload resolution on that lookup set with the given arguments succeeds.
Qualified lookup of T::operator() in the calling context succeeds and performing overload resolution on that lookup set with the given arguments succeeds.
Something else?
To proceed from here (for me anyway) I would like to understand why the standard didn't simply say that f(123) means f.operator()(123);, the former being ill-formed if and only if the latter is ill-formed. The motivation behind the actual wording might reveal the intent and therefore which compiler's behaviour matches the intent.
Consider the following code:
struct A {
int propose();
};
struct A1 : A {
int propose(int);
using A::propose;
};
struct B1 : A1 {
protected:
using A1::propose;
public:
using A::propose;
};
int main() {
B1().propose();
}
Let's compile this: g++ -std=c++11 main.cpp.
I'm getting the following compiler error using GNU 4.8.1:
main.cpp: In function 'int main()':
main.cpp:2:9: error: 'int A::propose()' is inaccessible
int propose();
^
main.cpp:18:18: error: within this context
B1().propose();
However, this code compiles in AppleClang 6.0.0.6000056.
I understand that there is no need for the using in B1, (in my code was necessary, but I had 1 using too much by mistake). In any case, why Clang compiles it? Is this expected?
In [namespace.udecl], we have:
When a using-declaration brings names from a base class into a derived class scope, member functions and
member function templates in the derived class override and/or hide member functions and member function
templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a
base class (rather than conflicting).
The standard explicitly says that names brought in will not conflict with names in a base class. But it doesn't say anything about bringing in conflicting names.
The section also says:
A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multiple
declarations are allowed. [ Example:
struct B {
int i;
};
struct X : B {
using B::i;
using B::i; // error: double member declaration
};
—end example ]
And interestingly, in the following example it's GCC that happily compiles it (and prints A) while Clang allows the construction of a C but rejects the call to foo as ambiguous:
struct A {
void foo() { std::cout << "A\n"; }
};
struct B {
void foo() { std::cout << "B\n"; }
};
struct C : A, B {
using A::foo;
using B::foo;
};
int main()
{
C{}.foo();
return 0;
}
So the short answer is - I suspect this is underspecified in the standard and that both compilers are doing acceptable things. I would just avoid writing this sort of code for general sanity.
The declaration is legal.
Calling it is legal and should work anywhere, and it can only be called from the class and derived classes, and it can be called from within any class. You'll note that this makes little sense.
There are no rules that ban that construct in declarations (importing the name twice from two different base classes with the same signature), and it is even used in "real" code where the derived class goes and hides the name after they are imported.
If you don't hide it, you are in the strange situation where the same function A::propose is both protected and public at the same time, as it is named twice (legally) in the same scope with different access control. This is ... unusual.
If you are within a class, a sub-clause says you can use it:
[class.access.base]/5.1
A member m is accessible at the point R when named in class N if — (5.1) m as a member of N is public
and propose is clearly public. (it is also protected but we don't have to keep reading for that case!)
Elsewhere, we have a contradiction. You are told you can use it everywhere without restriction [class.access]/1(3). And you are told that you can only use it in certain circumstances [class.access]/1(2).
I am uncertain how to resolve that ambiguity.
The rest of the logic train:
In [namespace.udecl]/10 we have:
A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multiple declarations are allowed.
And [namespace.udecl]/13:
Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region
so each of those using X::propose; are declarations.
[basic.scope] has no applicable restrictions on two functions of the same name in a scope, other than [basic.scope.class]/1(3) which states that if reordering of declarations changes the program, the program is ill-formed. So we cannot say that the later one wins.
Two declarations of member functions in the same scope are legal under [basic.scope]. However, under [over], there are restrictions on two member functions with the same name.
[over]/1 states:
When two or more different declarations are specified for a single name in the same scope, that name is said to be overloaded
And there are some restrictions on overloading. This is what usually prevents
struct foo {
int method();
int method();
};
from being legal. However:
[over.load]/1 states:
Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. A program is ill-formed if it contains two such non-overloadable declarations in the same scope. [Note: This
restriction applies to explicit declarations in a scope, and between such declarations and declarations made through a using-declaration (7.3.3). It does not apply to sets of functions fabricated as a result of name lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions). —end note
the note explicitly permits symbols introduced via two using-declarations from being considered by the overloading restrictions! The rules only apply to two explicit declarations within the scope, or between an explicit declaration within the scope and a using declaration.
There are zero restrictions on two using-declarations. They can have the same name, and their signatures can conflict as much as you'd like.
This is useful, because usually you can go and then hide their declaration (with a declaration in the derived class), and nothing goes wrong [namespace.udecl]/15:
When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).
However, this is not done here. We then call the method. Overload resolution occurs.
See [namespace.udecl]/16:
For the purpose of overload resolution, the functions which are introduced by a
using-declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function, and in all other respects the function remains a member of
the base class.
So we have to treat them as if they are members of the derived class for the purpose of overload resolution. But there are still 3 declarations here:
protected:
int A::propose(); // X
int A1::propose(int); // Y
public:
int A::propose(); // Z
Thus the call to B1().propose() considers all 3 declarations. Both X and Z are equal. They, however, refer to the same function, and overload resolution states there is an ambiguity if two different functions are selected. So the result is not ambiguous. There may be access control violations, or not, depending on how you read the standard.
[over.match]/3
If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is ill-formed. When overload resolution succeeds, and the best viable function is not accessible (Clause 11) in the context in which it is used, the program is ill-formed.
For example, the following code piece compiles with gcc-4.9 and clang-602
class Base
{
public:
static void foo() {}
void badfoo(int i) {}
};
template <typename T>
class Derived : public Base
{
public:
void bar() { Base::foo(); }
void badbar() { Base::badfoo(); } // compiles ok
//static void badbar() { Base::badfoo(); } // compile error
//void worsebar() { Base::nonexist(); } // compile error
};
int main()
{
return 0;
}
But the commented out lines won't compile.
My questions are:
Why badbar() compiles but worsebar() doesn't ?
If I change badbar() to static it won't compile either, regardless if base::badfoo is static or not.
Does the standard say anything about what should be checked in this situation ? gcc4.4 actually refuses to compile even badbar().
Update:
Problem 1 has been explained by a number of answers, but it seems compilers sometimes go the extra mile to check overload as well, it happens to gcc 4.4.3 and 4.8.2, but not 4.7.2 and 4.9.1.
Problem 2: As Marco A. pointed out, clang won't compile but gcc4.9 will still pass. However, gcc4.2 and gcc4.4 both reject the code, and the error they are complaining is "no matching function" rather than "calling non-static member without an object" in clang. There's seems to be no conclusive answer to this question, so I'm adding a language-lawyer tag as Daniel Frey suggested.
More Update:
I think for question 2 the answer is pretty clear now: it's up to the compiler whether adding static declaration will change the diagnosis. It varies from compiler to compiler and different versions of the same compiler. The language lawyer didn't show up, I'm going to accept Daniel Frey's answer as it best explained the first question. But answers from Marco A. and Hadi Brais also worth reading.
The standard only requires the name-lookup to happen at phase 1, when the template is first parsed. This turns up badfoo in badbar which is why the code compiles. The compiler is not required to do the overload resolution at that time.
The overload resolution (which always happens as a separate step after the name lookup) is then performed in phase 2 when badbar is instantiated - which is not the case in your example. This principle can be found in
3.4 Name lookup [basic.lookup]
1 The name lookup rules apply uniformly to all names (including typedef-names (7.1.3), namespace-names (7.3), and class-names (9.1)) wherever the grammar allows such names in the context discussed by a particular rule. Name lookup associates the use of a name with a declaration (3.1) of that name. Name lookup shall find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (Clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (Clause 5).
(Emphasis mine)
I'd therefore say that the compiler(s) are correct to accept the code, although I'm not sure that they are required to do so.
To see the code being rejected, you need instantiate badbar.
Consider [temp.res]/8:
If no valid specialization can be generated for a template, and that
template is not instantiated, the template is ill-formed, no
diagnostic required.
This (in particular the "no diagnostic required" bit) makes any compiler's behaviour compliant with respect to worsebar. Implementations' discrepancies on this kind of code are just QoI issues - common compilers do some analysis and will complain. It is hard to say when exactly, and you should be prepared to come back to template code when upgrading or switching your implementation.
To make some clarity.. this version of the code compiles just fine on clang and gcc
class Base
{
public:
static void foo() {}
void badfoo(int a) {}
};
template <typename T>
class Derived : public Base
{
public:
void bar() { Base::foo(); }
void badbar() { Base::badfoo(); }
};
since
[temp.res]/p8
If no valid specialization can
be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic
required.
Both gcc and clang aren't required to diagnose this. This one also falls in the same case as above (clang emits an error, gcc doesn't)
class Base
{
public:
static void foo() {}
void badfoo(int a) {}
};
template <typename T>
class Derived : public Base
{
public:
void bar() { Base::foo(); }
static void badbar() { Base::badfoo(); }
};
The case with
void worsebar() { Base::nonexist(); }
is different since it violates name lookup [temp.res]/p9
When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1,
3.4.2) are used for non-dependent names
and [temp.res]/p10
If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations)
for that name shall be in scope at the point where the name appears in the template definition
Disclaimer: all of the above does not apply to MSVC which happily postpones all this stuff to the second phase of the lookup.
Edit:
in the case
class Base
{
public:
static void foo() {}
void badfoo(int i) {}
};
template <typename T>
class Derived : public Base
{
public:
static void badbar() { Base::badfoo(); } // static function
clang triggers an error while gcc doesn't. This falls in the first case since name lookup is successful but clang performs an additional check: since badfoo is a member function it tries to construct a valid implicit member reference expression. It then catches the fact that a member function is implicitly being called from a static function and detects the context mismatch. This diagnostic is entirely up to the compiler at this point (it wouldn't in case of an instantiation).
Before it instantiates any types or emits any code, the compiler incrementally builds a table of all symbols that have been declared. If an undeclared symbol has been used, it emits an error. That's why worsebar won't compile. On the other hand, badfoo has been declared and so badbar compiles. At this early point in the compilation process, the compiler won't check whether the call to badfoo actually matches the declared badfoo.
Since the Derived type has not been instantiated anywhere in the code, the compiler will not emit any code regarding it. In particular, badbar will just be neglected.
Now when you declare an instance of Derived (such as Derived< int >) but without using any of its members, the compiler will just create a type with those members that have been used and omit the others. Still, no error regarding badbar.
However, when declaring an instance of Derived and calling badbar, an instantiation of the badbar method would be required and so the compiler will create a type with badbar and compile it. This time, the compiler notices that badfoo is not actually declared and therefore emits an error.
This behavior is documented in the C++ standard in section 14.7.1.
Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist.
Finally, if badbar was static and was instantiated by the compiler (because it has been used) then the compiler will emit an error that badfoo does not exist. Now if you pass an integer argument to badfoo, another error will be emitted indicating that a static method cannot access an instance member because there is no instance in the first place.
Edit
The compiler is not obliged to NOT report semantic errors in uninstantiated template types. The standard just says that it does not have to, but it can. Regarding where to draw the line is open for debate. See this discussion about a related issue in clang:
which uninstantiated templates do we analyze? For performance reasons, I don't think we should analyze all the uninstantiated templates, as we may find ourselves repeatedly analyzing a huge portion of the Boost and the STL, etc.
So uninstantiated templates analysis changes with different versions of clang and gcc in different ways. But again, as per the standard: There's no requirement to report errors in uninstantiated templates, of course.
At first if you would instantiate Devired and try to call badbar there would be a compilation error:
// ...
int main()
{
Derived<int> d;
d.badbar();
return 0;
}
produces
error: too few arguments to function call, single argument 'i' was not specified
void badbar() { Base::badfoo(); } // compiles ok
~~~~~~~~~~~~ ^
The compiler doesn't compile the code, that is not instantiated.
I try to compile the following code with clang (version 3.0), but it gives me this error
error: no matching member function for call to 'a'
in the call __a.a<0>(). Then I try with g++ (version 4.2.1) and it compiles and works as expected (print out 1 2).
#include <iostream>
struct A {
template <int> int a() { return 1; }
};
struct B: A {
using A::a;
template <int,int> int a() { return 2; }
};
int main(int, char **) {
B __a;
std::cout << __a.a<0>() << " " << __a.a<0,0>() << std::endl;
return 0;
}
I try to look to the standard but I have not found anything that explains which is the correct behavior of compiler. Now, my question is which is the correct behavior, and if clang works correctly, how I can modify my code to work as expected?
Digging through both the C++03 and C++11 standard, it doesn't look good for your code to be valid and well-formed. C++03 seems to have allowed this, while a change in the wording of the C++11 standard seems to have disallowed this.
§7.3.3 [namespace.udecl] (Both standards)
p12 (C++03) When a using-declaration brings names from a base class into a derived class scope, member functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting).
Note that this wording doesn't mention any member function templates.
p15 (C++11) When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).
Note the mentioning of member function templates in the new wording. Also note, that the list that determines if a derived class member overrides / hides a base class member doesn't mention the template-parameter-list of the member function template as an identifying point, it is being ignored for this purpose.
I might be interpreting this completely wrong, but it seems Clang is the conforming compiler here, and GCC aswell as MSVC10 are non-conforming according to the new wording.