Перечисления и указатели на члены

Недавно я попытался создать класс is_class , и мне нужен был способ, позволяющий компилятору различать типы перечисления и типы классов, для которых определены операторы преобразования. Видя, что классы, структуры и объединения являются единственными типами, совместимыми с функциями указателя на член, я решил, что компилятор определит, был ли тип, используемый для создания экземпляра шаблона is_class , в свою очередь, совместим с указатели на функции-члены. Столкнувшись с несколькими проблемами, я решил проверить поведение перечислений при использовании в сочетании с указателем на члены и получил несколько дурацких результатов. Следующий сегмент иллюстрирует первую причуду:

enum ENUM {};
void Test(void (ENUM::*pmem) (void))
{
    /* ... */
}
Test(NULL);

При компиляции с помощью Microsoft Visual C ++ 2010 указатель на член в определении функции: (ENUM :: * pmem)

выделен красным, и наведение курсора на объявление показывает ошибку:

Ошибка: «ENUM» не является типом класса

Однако компилятор анализирует этот сегмент, не обнаруживая ошибок, присваивая pmem в NULL . Мне интересно, что компилятор позволил бы это увидеть, поскольку типы перечисления не являются классами, структурами или союзами и, следовательно, не могут обладать собственными методами.

Второй интересный момент возник при создании функции шаблона, взяв указатель -to-member аргумент, тип которого варьируется:

template<class _Ty>
void Test_Template(void (_Ty::*pmem) (void))
{
    /* ... */
}

Конечно, чтобы использовать эту функцию, она должна быть явно квалифицирована:

Test_Template<ENUM>(NULL);

Этот вызов, однако, генерирует ошибку, указывающую:

недопустимый явный аргумент (ы) шаблона для 'void Test (void (__thiscall _Ty :: *) (void))'

Я исправил эту проблему, создав дополнительный шаблон функции, прототип которого будет соответствовать любому вызову, который не соответствует прототипу предыдущей функции шаблона (в котором использовалось многоточие).

Вопросы:

  1. Почему совместимо ли перечисление с указателями на элементы?

  2. Почему существует точное совпадение при вызове нешаблонной функции Test , в то время как компилятор генерирует ошибку для шаблона Test_Template явная квалификация?

11
задан Björn Pollex 5 March 2011 в 20:29
поделиться