Публичное "using" = decltype (<private>) - PullRequest
0 голосов
/ 19 октября 2018

В следующем (свернутом) коде у меня есть публичное объявление using, которое ссылается на decltype(something_private): using Foo = decltype(something_private<T>).

В Clang, но не в GCC, это не компилируется, посколькуprivate.

Вопросы:

  1. Что такое элегантное решение, если я не хочу делать func<T>() публичным.
  2. Где в стандарте C ++ (C ++ 11) резервная копия Clang здесь указана правильно?

Приведенный ниже код завершается ошибкой со следующим кодом ошибки на Clang (3.9 - 7.0)) но основывается на GCC (4.8.4 - 8.2):

class A {
private:
    template <class T>
    static auto func() -> T; // The actual return type is much
       // more complicated, so `using Foo = T` would not work.

public:
    template <class T>
    using Foo = decltype(func<T>());
};

int main(int, char**) {
    A::Foo<int> y;
    return y;
}

Clang 7.0 output:

<source>:10:24: error: 'func' is a private member of 'A'
  using Foo = decltype(func<T>());
                       ^~~~~~~

<source>:14:7: note: in instantiation of template type alias 'Foo' requested here
   A::Foo<int> y;
          ^

<source>:6:15: note: declared private here
  static auto func() -> T;
              ^

1 error generated.
Compiler returned: 1

https://godbolt.org/z/zD4Hk5

1 Ответ

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

Я не смотрел в стандарте для цитирования, но есть обходной путь для вас.Поскольку это работает, это заставляет меня думать, что в Clang просто есть ошибка.Когда функция находится непосредственно в A, она обрабатывает псевдоним типа, как если бы она была в контексте вызывающей стороны, но перемещение функции в структуру решает это.Мех.В последнее время я много занимался портированием на g ++ / clang, и хотя я специально не сталкивался с этим, пахло некоторыми вещами, с которыми я столкнулся.

class A {
private:
  struct X {
    template <class T>
    static auto func() -> T;
  };

public:
  template <class T>
  using Foo = decltype(X::func<T>());
};

void bar() {
   A::Foo<int> y;
}

https://godbolt.org/z/ozIS-r

ОБНОВЛЕНИЕ: добавленная цитата.

Я думаю, что это прямо отвечает на ваш вопрос, и этот лязг здесь не так.

N4778 (последнее, что я нашел), 10.8 / p4 (стр. 259) ... [Примечание: поскольку контроль доступа применяется к именам, если контроль доступа применяется к имени typedef, только доступностьсамо имя typedef считается.Доступность объекта, на который ссылается typedef, не рассматривается.

...