c++ - 为什么我不能在带模板的派生类中使用基类的别名?

标签 c++ templates c++11 type-alias

考虑这个 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 既可以作为基类的成员访问,也可以作为子类的成员访问?

最佳答案

非限定查找不查找类模板中的依赖基类。

所以在这里:

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>依赖基类.为了在那里查找,您必须进行合格名称查找(这就是您在 StartSession2 中所做的):

template <typename Socket>
class StartSession : public Step<Session<Socket> >
{
protected:
   typename Step<Session<Socket>>::Session_ptr m_session;
   // ...
};

或者自己添加别名:

using Session_ptr = typename Step<Session<Socket>>::Session_ptr;

关于c++ - 为什么我不能在带模板的派生类中使用基类的别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334150/

相关文章:

c++ - 将修改后的数组值传递回 C++ 中的主函数

c++ - 如何为 ostream 的 operator<< 模板

java - 玩!在我的模板中渲染另一个模板

Javascript 在本地工作,但上传到服务器时出现错误

c++ - 用于初始化 2D std::array 成员的初始化列表

c++ - UML:具有参数依赖关系的模板类之间的继承

c++ - 如何避免在头文件中定义整个模板类

c++ - switch 中的 throw 语句

c++ - 复制字符串

c++ - 通过其成员的地址激活嵌套 union 是否合法?