2012-03-07 3 views
0

я боролся всю ночь с компилятором и я бегу из идей ...CRTP внутри пространства имен против typdefs и друзей

У меня есть строительство 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 

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

веселит

ответ

0

Ваши заявления 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.

+0

Thx! это решило это отлично. – moiself