我们如何在子类中键入或重新定义模板化嵌套类?

时间:2010-02-18 01:26:37

标签: c++ templates

请考虑以下事项:

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //How do we typedef of redefine Base<T>::Nested?
    using Base<T>::Nested; //This does not work
    using Base<T>::template<typename U> Nested; //Cannot do this either
    typedef typename Base<T>::template<typename U> Nested Nested; //Nope..

    //now we want to use the Nested class here
    template <typename U>
    Class NestedDerived : public Nested { };

    //or like this:
    Nested<int> nestedVar; // obviously does not work
};

如何在Derived类中使用模板嵌套类?在当前版本的C ++标准中可以做到这一点吗?

4 个答案:

答案 0 :(得分:10)

实际上using的工作方式与宣传的一样,它只是没有摆脱模板中的依赖名称问题,而且目前无法直接为模板设置别名(将fixed in C++0x):

template <class T>
struct Base {
    template <class U> struct Nested {};
};

template <class T>
struct Derived : Base<T> {
    using Base<T>::Nested;

    // need to prefix Nested with template because
    // it is a dependent template:
    struct X : Base<T>::template Nested<int> {};

    // same here:
    template<class U>
    struct Y : Base<T>::template Nested<U> {};

    // data member, typename is needed here:
    typename Base<T>::template Nested<int> data;
};

void f() { 
    Derived<int>::Nested<int> n; // works fine outside
}

在模板中使用Derived<T>::Nested时还有另一种可能的 gotcha ,但这又是一个依赖名称问题,而不是与继承相关的问题:

template<class T>
void g() {
    // Nested is a dependent type and a dependent template, thus
    // we need 'typename' and 'template':
    typedef typename Derived<T>::template Nested<int> NestedInt;
}

请记住,依赖于模板参数的名称必须是

  • 如果是依赖类型,则以typename为前缀:typename A<T>::B
  • 如果是依赖模板,则直接加template前缀:A<T>::template f<int>()
  • 如果两者都是:typename A<T>::template B<int>
  • typename在基类列表中是非法的:template<class T> struct A : B<T>, C<T>::template D<int> {};

答案 1 :(得分:2)

这似乎有效:
编辑:添加了更多行以显示第一个模板声明。感谢Samir Talwar纠正我的格式!)

template <typename T, typename U> 
class Derived : public Base<T> { 
  public: 
    typedef typename Base<T>::template Nested<U> Nested;

    class NestedDerived : public Nested { }; 

    Nested nestedVar;
};

答案 2 :(得分:0)

试试这个:

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //How do we typedef of redefine Base<T>::Nested?
    //using Base<T>::Nested; //This does not work
  //using Base<T>::template<typename U> Nested; //Cannot do this either
  //typedef typename Base<T>::template<typename U> Nested Nested; //Nope..

    //now we want to use the Nested class here
  template <typename U>
  class NestedDerived : public Base<T>::template Nested<U> { };
};

int main()
{
  Base<int>::Nested<double> nested;

  Derived<int>::NestedDerived<double> nested_derived;

  return 0;
}

在slackware 13上使用gcc 4.3.3编译好了

答案 3 :(得分:0)

我仍然不能100%确定你想要什么,但你可以试试 这是在Visual Studio上编译的

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //now we want to use the Nested class here
    template <typename U>
    class NestedDerived : public Nested<U> { };
};

int _tmain(int argc, _TCHAR* argv[])
{
Base<int>::Nested<double> blah2;
Derived<int>::NestedDerived<int> blah;

return 0;
}