Член шаблона не-шаблонного класса в качестве друга - PullRequest
0 голосов
/ 25 мая 2018

Следующий фрагмент отлично компилируется с помощью 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!
}

В чем может быть разница между статическим членом шаблона не-шаблонного класса и функцией свободного шаблона в этом контексте?

1 Ответ

0 голосов
/ 09 октября 2018

Я обнаружил ошибку, сообщенную для 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;
}

Результат:

$ 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.
...