CRTP внутри пространства имен против typdefs и друзей - PullRequest
0 голосов
/ 08 марта 2012

Я всю ночь боролся с компилятором, и у меня кончились идеи ...

У меня есть конструкция CRTP внутри пространства имен с защищенной функцией. Производный класс (также внутри этого пространства имен) определен по типу с другим именем.

рядом с этим у меня есть класс (также определен с другим именем) со статической функцией, которая пытается вызвать эту функцию. Поэтому я начинаю заводить друзей, но все равно компилятор (в моем случае VS 2010) не предоставит мне доступ к этой функции.

поскольку некоторый код, вероятно, более понятен:

namespace foobar
{
namespace internal
{
    template <typename T>
    class A
    {
        friend class E;

    protected:
        void foo()
        {
            static_cast<T*>(this)->_foo();
        }
    };

    class B : public A<B>
    {
        friend class E;
        friend class A<B>;

    protected:
        void _foo()
        {
            printf("Foo from B\n");
        }
    };
}

typedef internal::B C;

class D
{
public:
    static void Bar();

};

typedef D E;

    void D::Bar()
    {
        C mB;
        mB.foo();
    }   
}//foobar namespace

Кто-нибудь может сказать мне, что я здесь не вижу и как это можно решить?

ура

1 Ответ

0 голосов
/ 08 марта 2012

Ваши объявления friend class E Форвард-объявление class foobar::internal::E, которое не имеет ничего общего с class foobar::D. Вы должны объявить D и E, прежде чем объявить их друзьями:

namespace foobar
{
  class D;
  typedef D E;

  namespace internal
  {
    template <typename T>
    class A
    {
      friend E;
      // ...

Обратите внимание, что это работает только для C ++ 11. Для C ++ 03 вы вообще не можете объявить typedef как друга, вам нужно написать friend class ::foobar::D.

...