во время компиляции некоторого кода, который я натолкнулся на ошибку компилятора, которая показалась мне странной и связана с наследованием, вложенными классами, использованием объявлений и модификаторами доступа.
По сути, целью производного типа является раскрытие вложенного защищенного класса базового типа.
Следующий короткий пример, демонстрирующий проблему:
class Base
{
protected:
struct Nested
{
enum value_enum
{
val = 0,
val2,
val3
};
};
};
class Derived : public Base
{
public:
using Base::Nested;
};int main(int argc, char** argv)
{
//Base::Nested aa; // error, as (I) expected
//Base::Nested::value_enum ab; // error, as (I) expected
Derived::Nested ba; // works, as (I) expected
Derived::Nested::value_enum bb; // MSVC error, as (I) did not expectreturn 0;
}
Увидеть жить.
MSVC11 (v11.00.61030) заглушает этот код со следующей ошибкой:
ошибка C2248: «Base :: Nested»: невозможно получить доступ к защищенной структуре, объявленной в классе «Base»
И GCC, и Clang компилируют это правильно, поэтому без возможности процитировать соответствующие части из стандарта, я бы сказал, что это ошибка MSVC.
Есть ли способ обойти это с MSVC?
Для MSVC работает следующий обходной путь:
class Derived : public Base
{
public:
using Base::Nested;
typedef Base::Nested::value_enum value_enum; // add this
};
int main(int argc, char** argv)
{
//Base::Nested aa; // error, as (I) expected
//Base::Nested::value_enum ab; // error, as (I) expected
Derived::Nested ba; // works, as (I) expected
Derived::value_enum bb = Derived::value_enum::val; // now works in MSVCreturn 0;
}