Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template type alias visibility compiler disagreement

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.

like image 337
florestan Avatar asked Nov 07 '20 22:11

florestan


Video Answer


1 Answers

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
like image 118
cigien Avatar answered Oct 21 '22 06:10

cigien