作为朋友的非模板类的模板成员

Ser*_*eyA 15 c++ templates language-lawyer

下面的代码片段由gcc,icc和msvc(最新的问题)精确编译,但是<source>:6:9: error: calling a private constructor of class 'B<int>'在标记的行中叮当作响.然而它适用于免费模板功能,如代码所示:

struct A {
    template<class T>
    static void create () {
        T();
    }
};

template<class T>
void create() {
    T();
}

template<typename T>
struct B {

    friend void A::create<B>();
    friend void create<B>();

    private:
    B() = default;
};

int main() {
     A::create<B<int>>(); // clang trips here
     create<B<int>>(); // fine!
}
Run Code Online (Sandbox Code Playgroud)

在此上下文中,非模板类的静态模板成员与自由模板函数之间可能有什么区别?

P.W*_*P.W 1

我发现 Clang 报告了一个错误,“不允许访问引用朋友私有嵌套类型的公共模板别名声明”,这似乎与此问题类似,因为它与朋友(OP 中结构内的模板)访问有关类的私有成员。

失败的测试用例是:

struct FooAccessor
{
    template <typename T>
    using Foo = typename T::Foo;
};

class Type
{
    friend struct FooAccessor;        
    using Foo = int;
};

int main()
{
    FooAccessor::Foo<Type> t;
}
Run Code Online (Sandbox Code Playgroud)

结果是:

$ clang++ test.cpp -std=c++11
test.cpp:4:5: error: 'Foo' is a private member of 'Type'
    using Foo = typename T::Foo;
    ^
test.cpp:11:11: note: implicitly declared private here
    using Foo = int;
          ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)