Рассмотрим C++ код:Почему я не могу использовать псевдоним из базового класса в производном классе с шаблонами?
template<typename Session>
class Step
{
public:
using Session_ptr = boost::shared_ptr<Session>;
protected:
Session_ptr m_session;
public:
inline Step(Session_ptr session) :
m_session(session)
{}
};
template<typename Socket>
class Session
{
public:
Socket a;
Session(Socket _a):
a(_a)
{}
};
template <typename Socket>
class StartSession : public Step<Session<Socket> >
{
protected:
Session_ptr m_session; //Unknown type Session_ptr
public:
inline StartSession(Session_ptr session) :
Step<Session<Socket> >(session)
{}
void operator()(const boost::system::error_code& ec);
};
template <typename Socket>
class StartSession2 : public Step<Session<Socket> >
{
protected:
typename Step<Session<Socket> >::Session_ptr m_session;
public:
inline StartSession2(typename Step<Session<Socket> >::Session_ptr session) :
Step<Session<Socket> >(session)
{}
void operator()(const boost::system::error_code& ec);
};
int main(int argc, char * argv[])
{
Step<Session<int> >::Session_ptr b(new Session<int>(5)); //no problem
StartSession<int >::Session_ptr bb(new Session<int>(5)); //gcc ok, clang refuses to remember the symbol since the class has errors
StartSession2<int >::Session_ptr bbb(new Session<int>(5)); //no problem
std::cout << b->a; // ok
std::cout << bb->a; // gcc ok, clang bb not declared
std::cout << bbb->a; // ok
return 0;
}
Как вы можете видеть, есть какие-то странные (для меня по крайней мере) вещи здесь происходит ...
Во-первых, почему не Session_ptr
доступны в ребенка классы? Я знаю, потому что они шаблонный класс, которые делают вещи более сложными ... Но я не вижу никакой двусмысленности здесь, что делает использование typename
обязательного ...
Тогда, почему в основном, Session_ptr
доступен либо как член базового класса, либо как член дочернего класса?