flo*_*tan 8 c++ templates language-lawyer
以下示例使用 gcc 编译,但不使用 clang 编译。哪个编译器是正确的,为什么?
#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>);
}
Run Code Online (Sandbox Code Playgroud)
Clang 抱怨说'f' is a private member of 'Foo'。我认为这是不正确的,因为f是从内部访问的Foo,因此应该是可见的。有趣的是,如果T不是模板,它也能工作。
现场代码在这里。
这是一个clang bug,其中 clang 无法解析成员别名模板中使用的名称的正确访问控制。
这个问题是错误的一个例子,其中友元类成员的名称的访问控制被错误地解析。
在您的示例中,您有一个静态成员模板f,为此我们只需要temp.mem#2
...访问控制规则适用于成员模板名称。...
所以f在 的声明中确实可见T,并且代码是有效的。
请注意,链接帖子中提到的修复在这里也有效,因为它是相同的错误:
template<typename U, typename X = decltype(f<U>())>
using T = X; // ok
Run Code Online (Sandbox Code Playgroud)