Это, вероятно, должно помочь (воспроизводится также и в не шаблонной ситуации)
struct A{
protected:
void f(){}
};
struct B : A{
void g(){&A::f;} // error, due to Standard rule quoted below
};
int main(){
}
VS дает "A :: f": не может получить доступ
защищенный член объявлен в классе
'А' "
Для того же кода, Комо дает
"ComeauTest.c", строка 7: ошибка:
защищенная функция "A :: f" (объявлена в
строка 3)
недоступен через указатель «A» или объект void g () {& A :: f;}
^
"ComeauTest.c", строка 7: предупреждение:
выражение не имеет никакого эффекта void
г () {& A :: F;}
Вот фиксированный код, который достигает желаемых намерений
struct A{
protected:
void f(){}
};
struct B : A{
void g(){&B::f;} // works now
};
int main(){
}
Итак, почему первый фрагмент кода не работает?
Это из-за следующего правила в C ++ Standard03
11.5 / 1- "Когда друг или функция-член производного класса ссылаются
защищенная нестатическая функция-член
или защищенный нестатический элемент данных
базовый класс, применяется проверка доступа
в дополнение к описанным ранее
в пункте 11.102) За исключением случаев формирования
указатель на член (5.3.1),
доступ должен быть через указатель на,
ссылка или объект
сам производный класс (или любой класс
происходит из этого класса) (5.2.5). Если
доступ должен сформировать указатель на
член, спецификатор вложенного имени
должен назвать производный класс (или любой
класс, производный от этого класса).
Итак, измените возврат в операторных функциях следующим образом
return (boolean_test() == true) ? &safe_bool<void>::this_type_does_not_support_comparisons : 0; //46
return (static_cast<const T*>(this))->boolean_test() ? &typename safe_bool<T>::this_type_does_not_support_comparisons : 0;
РЕДАКТИРОВАТЬ 2: Пожалуйста, игнорируйте мои объяснения. Дэвид прав. Вот к чему это сводится.
struct A{
protected:
int x;
};
struct B : A{
void f();
};
struct C : B{};
struct D: A{ // not from 'C'
};
void B::f(){
x = 2; // it's own 'A' subobjects 'x'. Well-formed
B b;
b.x = 2; // access through B, well-formed
C c;
c.x = 2; // access in 'B' using 'C' which is derived from 'B', well-formed.
D d;
d.x = 2; // ill-formed. 'B' and 'D' unrelated even though 'A' is a common base
}
int main(){}