2010-02-02 4 views
6

у меня есть следующие иерархии классов:C++ Compiler ошибка с CRTP

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» перед директивой use в классе_b, решает проблему как для gcc, так и для VS. Должен ли раздел доступа класса, в котором применяется директива using, переопределяет режим деривации (открытый, закрытый) базового класса?

Короче это за

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

ответ

3

Что вы делаете здесь, в разрешении неоднозначности путем импорта символа в классы частного пространства имен. Следовательно, это метод затенения и изменения его видимости для частного. Вы не можете иметь две функции с одним и тем же прототипом, как частным, так и общедоступным, поэтому f теперь является приватным.

По крайней мере, GCC считает, что using should be able to change the visibility функции.

Сходные ссылки, однако, содержатся в GCC bug database, показывают, что использование на самом деле не должно зависеть от объема.

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

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

Поэтому ответы будут:

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

Ничто не находится в частном пространстве имен или объема. и директива using не рассматривает часть доступа класса, в котором она вызвана, однако добавление public до того, как директива use решит проблему. Я считаю, что в этом случае gcc и VS виноваты, не так ли? – 2010-02-02 01:44:05

+2

@darid, в приведенной выше ссылке вы увидите, что по крайней мере в случае GCC она была изменена так, как теперь явно. –

+0

@Kornel: Это отличный ответ, я бы хотел добавить, что я попробовал его с компилятором intel C++, и ему нравится, как это происходит с Комо.Интересно, возникает ли проблема с парсерным интерфейсом, Intel и Comeau получают их от EDG, но MS также поддерживает VSC++, что просто путает вещи все больше. – 2010-02-02 02:53:53

Смежные вопросы