簡體   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