Ошибка компилятора C ++ с CRTP - PullRequest
6 голосов
/ 02 февраля 2010

У меня есть следующая иерархия классов:

template <typename T>
class base
{
public:
   void f() {}
};

class class_a : public base<class_a> {};

class class_b : public base<class_b>, 
                public class_a 
{ 
   using base<class_b>::f; 
};

int main()
{
   class_b b;
   b.f();
   return 0;
}

Comeu и Intel C ++ v11 утверждают, что все хорошо, однако GCC (4.4.1) и VC ++ 2008, похоже, жалуются (http://codepad.org/KQPDsqSp), например:

g++ -pedantic -Wall -o test test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:5: error: ‘void base<T>::f() [with T = class_b]’ is inaccessible
test.cpp:14: error: within this context 

Я считаю, что код правильно сформирован, но я могу ошибаться, я надеюсь, что кто-то из сообщества SO C ++ мог бы дать некоторое представление об этой проблеме.

Примечание: Добавление «public» перед директивой using в class_b решает проблему как для gcc, так и для VS. Должна ли секция средства доступа класса, в которой применяется директива using, переопределить режим деривации (открытый, закрытый) базового класса?

Короче говоря, это

  • Ошибка компилятора - если да, то какой компилятор GCC, VS или Comeu, Intel
  • Правильно ли сформирован вышеуказанный код?
  • Заменяет ли секция доступа, в которой вызывается директива using, режим деривации базы?

1 Ответ

3 голосов
/ 02 февраля 2010

То, что вы здесь делаете, это устранение неоднозначности путем импорта символа в пространство имен классов private . Следовательно, это метод затенения и изменения его видимости на частный. У вас не может быть двух функций с одинаковым прототипом, как private, так и public, поэтому f теперь private.

По крайней мере, GCC считает, что использование должно иметь возможность изменить видимость функции.

Темные ссылки, найденные в База данных ошибок GCC , показывают, что использование не должно зависеть от области действия.

Самое главное, прямой ответ (C ++ Standard '03 - 7.3.3 / 15)

Псевдоним, созданный с помощью объявления-использования, имеет обычный доступ к объявлению члена.

Следовательно, ответы будут:

  • это ошибка в Comeau
  • нет, код плохо сформирован, по крайней мере, на C ++ 03 (не могу найти ничего связанного с C ++ 0x N3000)
  • да, вы можете изменить область доступа
...