假设我定义了一个使用模板参数T
的嵌套类的模板P
,如下所示:
template<class P> class T
{
public:
T(P& p) : p(p) {}
P& p;
typename P::Nested& get_nested() { return p.nested; }
};
如果我声明一个包含名为A
的嵌套类的类Nested
,我可以定义一个T<A>
类型的变量,没有问题:
class A
{
public:
class Nested
{
public:
int i;
};
Nested nested;
};
void test2a()
{
A a;
a.nested.i = 1;
T<A> t_a(a);
t_a.get_nested().i = 2;
}
现在,我想声明一个类B
,它以同样的方式包含一个名为Nested
的嵌套类,并继承自T<B>
,如下所示:
class B : public T<B>
{
public:
class Nested
{
public:
int i;
};
Nested nested;
};
上述代码的编译失败,错误:&#34; 嵌套不是 B &#34;
的成员我想我理解发生了什么:在输入模板时,由于继承,B类未完全定义。
但是,我想知道是否有办法做这样的事情......
感谢您的帮助。
答案 0 :(得分:6)
你需要推迟get_nested
的返回类型的分辨率,直到它被调用。
一种方法是使返回类型依赖于模板参数:
template<typename unused = void>
typename std::conditional<false, unused, P>::type::Nested&
get_nested() { return p.nested; }
另一种方式(自C ++ 14起)是使用返回类型推导:
auto& get_nested() { return p.nested; }
答案 1 :(得分:3)
我能用简单的
编译你的例子template<class P> class T
{
public:
T(P& p) : p(p) {}
P& p;
auto& get_nested() { return p.nested; }
};
另一种方法,利用与@ecatmur相同的技巧,但有点简单:
template<class R = P>
typename R::Nested& get_nested() { return p.nested; }
同样,在这里,编译器必须推迟对P::Nested
的评估,直到您致电get_nested()
。