The following example compiles with gcc but not with clang. Which compiler is right, and why?
#include <utility>
struct Foo {
private:
template<typename T>
static int f();
public:
template<typename U>
using T = decltype(f<U>());
};
int main () {
static_assert(std::is_same_v<Foo::T<float>, int>);
}
Clang complains that 'f' is a private member of 'Foo'
. I think this is not correct as f
is accessed from within Foo
and thus should be visible. Interestingly, it works if T
is not a template.
Live code here.
This is a clang bug, where clang doesn't resolve the correct access control for names used in member alias templates.
This question is an example of the bug, where the access control for names of members of friend classes is resolved incorrectly.
In your example, you have a static member template f
, and for that we only need temp.mem#2
... Access control rules apply to member template names. ...
So f
is indeed visible in the declaration of T
, and the code is valid.
Note that the fix mentioned in the linked post works here as well, since it's the same bug:
template<typename U, typename X = decltype(f<U>())>
using T = X; // ok
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