繁体   English   中英

在CRTP中使用模板参数的嵌套类

[英]Using nested class of template parameter in CRTP

假设我定义了一个模板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;
};

上面的代码编译失败,并显示错误消息:“ 嵌套不是B的成员”

我想我了解发生了什么:在输入模板时,由于继承,未完全定义类B。

但是,我想知道是否有任何方法可以做这样的事情...

感谢帮助。

您需要推迟get_nested返回类型的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; }

我能够简单地编译您的示例

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()为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM