13

我知道默认情况下编译器看不到“依赖名称”这一事实。但是在其他 SO 问题的回答中(herehere以及最终在 C++ 常见问题解答中) ,有人告诉我using声明可能会有所帮助。

所以我尝试了。

模板基类:

// regardless of the fact that members are exposed...
template<typename T>
struct TBase {
   typedef T MemberType;
   MemberType baseMember;
   MemberType baseFunction() { return MemberType(); }
};

还有一个派生类,使用基类的成员:

template<typename T>
struct TDerived : public TBase<T> {
   // http://www.parashift.com/c++-faq-lite/nondependent-name-lookup-members.html
   // tells us to use a `using` declaration.
   using typename TBase<T>::MemberType;
   using TBase<T>::baseFunction;
   using TBase<T>::baseMember;

   void useBaseFunction() { 
      // this goes allright.
      baseFunction();
      ++baseMember;

      // but here, the compiler doesn't want to help...
      MemberType t; //error: expected `;' before ‘t’
   }
};

在 ideone 上试过了。它有 gcc-4.3.3 和 gcc-4.5.1

这是预期的行为吗?我们应该如何解决访问父模板类成员类型定义的“依赖名称”法则?

4

1 回答 1

20

你可能想做:

using MemberType = typename TBase<T>::MemberType; // new type alias syntax

或者

typedef typename TBase<T>::MemberType MemberType; // old type alias syntax

该语法using Base::member;只能用于将非类型成员的声明带入范围。


另请注意,实际上这些都不是必需的,您可以限定每次使用(对于具有基数的类型,对于具有任一this->或基数的非类型),这将使符号依赖。

于 2012-11-15T20:40:46.827 回答