BaseAttribute ClosedPocketEntity::* ClosedPocketEntity::memberPtrArray[] = {
(BaseAttribute ClosedPocketEntity::*) &PocketEntity::depth,
(BaseAttribute ClosedPocketEntity::*) &ClosedPocketEntity::surfaceType
};
Первое преобразование указателя, которое вы вводите здесь, недопустимо. Из C ++ 03 §4.11 / 2 Указатель на преобразование члена :
Значение типа «указатель на член B типа cv T», где B - тип класса, может быть преобразовано в значение типа «указатель на член D типа cv T», где D - это тип производный класс (пункт 10) из B. Если B - недоступный (пункт 11), неоднозначный (10.2) или виртуальный (10.1) базовый класс D, программа, для которой это необходимо
Конверсия неправильная.
(Насколько я могу судить, формулировка в C ++ 11 не изменилась.)
&PocketEntity::depth
относится к типу RealAttribute PocketEntity::*
, поэтому даже преобразование в RealAttribute ClosedPocketEntity::*
будет некорректным, поскольку PocketEntity
является виртуальной базой ClosedPocketEntity
.
clang++
имеет это полезное сообщение об ошибке:
error: conversion from pointer to member of class 'PocketEntity'
to pointer to member of class 'ClosedPocketEntity'
via virtual base 'PocketEntity' is not allowed
Если вы удалили виртуальное наследование, преобразование по-прежнему недействительно в соответствии с GCC и clang:
error: cannot initialize an array element of type
'BaseAttribute ClosedPocketEntity::*'
with an rvalue of type
'RealAttribute PocketEntity::*'
Ничто из того, что я вижу в этом разделе стандарта, не позволило бы это преобразование (но учтите, что я здесь не в своей тарелке и вполне может что-то упустить в замечательных правилах преобразования C ++).
Компилятор, который вы использовали в Windows, допускает это как расширение или просто «делает то, что вы хотите» в этом случае. Другие компиляторы, похоже, имеют дело с этим принудительным неверным приведением.
Что касается того, как это исправить, боюсь, я понятия не имею. (Вы уверены, что вам нужен такой замысловатый дизайн?)