问题描述
考虑以下C ++代码:
Consider this C++ code :
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;
}
如您所见,这里发生了一些奇怪的事情(至少对我来说)...
As you can see, there are some strange (to me at least) things happening here...
首先,为什么在子类中不能访问Session_ptr
?我知道,因为这些是模板化的类,这会使事情变得更复杂...但是我看不出有任何强制使用typename
的歧义...
First, why isn't Session_ptr
accessible in the child classes ?I know because these are templated class, that make things more complicated... But I don't see any ambiguity here that makes the use of typename
mandatory...
然后,为什么在主目录中Session_ptr
既可以作为基类的成员又可以作为子类的成员来访问?
Then, why in the main, Session_ptr
is accessible either as member of the base class either as member of a child class ?
推荐答案
不合格的查找不在类模板的依赖基类中查找.
Unqualified lookup does not look in dependent base classes in class templates.
所以在这里:
template <typename Socket>
class StartSession : public Step<Session<Socket> >
{
protected:
Session_ptr m_session; // <== unqualified name lookup on Session_ptr
// ...
};
Step<Session<Socket>>
是StartSession<Socket>
的依赖基类.为了在那里查找,您必须进行 qualified 名称查找(这是您在StartSession2
中所做的事情):
Step<Session<Socket>>
is a dependent base class of StartSession<Socket>
. In order to lookup there, you'll have to do qualified name lookup (which is what you're doing in StartSession2
):
template <typename Socket>
class StartSession : public Step<Session<Socket> >
{
protected:
typename Step<Session<Socket>>::Session_ptr m_session;
// ...
};
或者只是自己添加别名:
Or simply add the alias yourself:
using Session_ptr = typename Step<Session<Socket>>::Session_ptr;
这篇关于为什么不能在带有模板的派生类中使用基类的别名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!