The following program defines two function templates, A::foo<>()
and B::foo<>()
, in two separate namespaces (A
and B
). The two function templates are identical in signature, and differ only in the default argument assigned to their second template parameter. Eventually, their names are brought into the scope of main()
by a corresponding pair of using
declarations:
#include <type_traits>
namespace A
{
template<
typename T,
typename = typename std::enable_if<
std::is_same<T, int>::value // Let this be condition C
>::type
>
void foo(T) { }
}
namespace B
{
template<
typename T,
typename = typename std::enable_if<
!std::is_same<T, int>::value // This is the negation of C
>::type
>
void foo(T) { }
}
int main() {
using A::foo;
using B::foo; // COMPILES: Is this legal?
foo(42); // Invokes A::foo(), non-ambiguous because of SFINAE
}
I would expect the second using
declaration to cause a compilation error here: after all, that is what I get when I try to define those two templates in the same namespace.
To my surprise, every compiler I tried this on (GCC 4.7.2, GCC 4.8.0 beta, ICC 13.0.1, Clang 3.2) compiles the program and invokes A::foo()
.
QUESTION #1: Is this correct? Is it perhaps a case of "no diagnostic required"? References to the C++11 Standard are encouraged.
Consider now this variation of the above program, that basically achieves the same effect using classes rather than namespaces:
#include <type_traits>
struct X
{
template<
typename T,
typename = typename std::enable_if<
std::is_same<T, int>::value // Here is condition C again
>::type
>
static void foo(T) { }
};
struct Y
{
template<
typename T,
typename = typename std::enable_if<
!std::is_same<T, int>::value // And the negation of C again
>::type
>
static void foo(T) { }
};
struct Z : X, Y
{
using X::foo;
using Y::foo; // COMPILES: Is this legal?
};
int main() {
Z::foo(42); // Invokes X::foo(), non-ambiguous because of SFINAE
}
This program too compiles on all the above mentioned compilers, while I would expect a compiler error to be caused by the second using
declaration.
QUESTION #2: Is this correct? Is it perhaps a case of "no diagnostic required"? References to the C++11 Standard are encouraged.