В следующем коде ( GodBolt Link ):
#include <utility>
struct Friend {
class Inner {
friend struct Friend;
int function() { return 0; }
};
using DirectResult = decltype(std::declval<Inner>().function());
template <typename T>
using IndirectResult = decltype(std::declval<T>().function());
};
int main() {
Friend::DirectResult direct{};
Friend::IndirectResult<Friend::Inner> indirect{};
return direct + indirect;
}
Clang совершенно доволен использованием DirectResult
, но будет жаловаться, что IndirectResult
пытается получить доступ private
функция Inner
:
<source>:13:55: error: 'function' is a private member of 'Friend::Inner'
using IndirectResult = decltype(std::declval<T>().function());
^
<source>:18:13: note: in instantiation of template type alias 'IndirectResult' requested here
Friend::IndirectResult<Friend::Inner> indirect{};
^
Я бы ожидал, что доступ будет в порядке, так как псевдоним шаблона объявлен в классе друга.
Однако в моем опыт Clang, как правило, прав (более чем g cc), когда дело доходит до интерпретации стандарта C ++.
Правильно ли Clang отвергать этот код? И если так, что я отсутствует?
Примечание: g cc 7.x, 8.x и 9.x принимают код.