2011-07-19 133 views
10

我正在制作一个内部工具类的模板类。模板的所有专业,希望同样的内部类:模板类的内部类是否可以是非模板类?

template<...> class Outer { 
    class Inner { }; 
}; 

这给了我Outer<...>::Inner但我希望所有Inner是同一类型,就好像我只是写:

class Inner { }; 
template <...> class Outer { }; 

,或者Outer人根本就不是一个模板类:

class Outer { 
    class Inner { }; 
}; 

给我Outer::Inner。我想对所有Outer<>Outer::Inner工作,如果可能的话(只是名称空间/清楚的原因)。否则,我当然可以将Inner移出。

+1

我相当肯定的答案是否定的,但我希望有人证明我是错的,因为我恰好是在类似情况下:) –

+1

我只是* *相当一定的答案是否定的,但我希望聪明的解决方法太... –

回答

15

嵌套类可以是非模板,但模板的每个实例都会有自己的嵌套类,因为他们(其他)无关的类型。你可以做

namespace detail { 

class Inner {}; 

} // detail 

template<...> 
class Outer { 
    typedef detail::Inner Inner; 
}; 
+0

清洁和性感的解决方案 –

+0

我忘了我的名字空间的细节 - 可以'现在,内部类隐藏着,就像它在一个“真正的”内部类中一样?或者任何包含代码的代码都可以拥有吗? – Nate

+0

@Nate上面的行为与任何'typedef'一样。只有一个声明不是一个定义(也就是'class Inner;'),并且它暗示的所有注意事项都可以使“Inner”不完整。但是必须声明它(名字'detail :: Inner'必须引用某个东西),否则它不能是'typedef'd。 –

0

它对每个外部实例化都是唯一的。即,

Outer<int>::Inner will be a different type from Outer<double>::Inner 
+1

这一事实是众所周知的OP,因为他已经明确表示在他的问题 –

13

我在过去所做的这个问题的方法是使用继承:

class DummyBase{ 
protected: 
    class Inner{ 
     //etc... 
    }; 
}; 

template<...> class Outer : public DummyBase{ 
    //etc... 
}; 
+0

+1这是聪明的,但我喜欢吕克的答案了。 –

+1

+1,因为这使得'Outer <> :: Inner'成为一个真正的类名。所以'类外<> ::内蒙古X;'或'友元类外<> ::内;',仍能正常工作,而'typedef'解决方案将失败在那里。 –