Я недавно столкнулся с некоторым расхождением между clang и gcc в отношении обнаружения void_t
свойств и информации защищенного / частного класса.Рассмотрим черту типа, определенную следующим образом:
#include <type_traits>
template<typename T, typename = void>
constexpr const bool has_nested_type_v = false;
template<typename T>
constexpr const bool has_nested_type_v
<T, std::void_t<typename T::type>> = true;
Приведенные примеры типов с защищенными или закрытыми вложенными type
классами и простой программой
#include "has_nested_type.hpp"
#include <iostream>
struct Protected {
protected:
struct type{};
};
struct Private {
private:
struct type{};
};
int main() {
std::cout << "Protected: "
<< (has_nested_type_v<Protected> ? "detected" : "not detected")
<< std::endl;
std::cout << "Private: "
<< (has_nested_type_v<Private> ? "detected" : "not detected")
<< std::endl;
}
clang compilesуспешно с неудачным обнаружением (как и ожидалось).Программа, компиляция и вывод воспроизводятся в wandbox здесь .
gcc не компилируется, выдавая диагностику.Эта ошибка может быть воспроизведена на wandbox здесь .
GCC выдает следующую ошибку для этой программы.
prog.cc:16:21: error: 'struct Protected::type' is protected within this context
<< (has_nested_type_v<Protected> ? "detected" : "not detected")
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:6:14: note: declared protected here
struct type{};
^~~~
prog.cc:19:21: error: 'struct Private::type' is private within this context
<< (has_nested_type_v<Private> ? "detected" : "not detected")
^~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:11:14: note: declared private here
struct type{};
^~~~
У меня вопрос, какое поведениесоответствует ли стандарт?Должен ли здесь произойти ошибка и выдать диагностическое сообщение, или GCC чрезмерно стремится?