派生自包含成员的类,其模板参数是基类

时间:2016-06-17 15:30:08

标签: c++ oop templates c++11

抱歉,如果这是重复的话,那么在这种情况下找不到任何东西是徒劳的。这本身不是名称解析问题,更多是模板/结构问题。

根据标题,有一种情况如下:

template< typename T > struct X;

struct Y {
    X< Y > & xy;
    Y( X< Y > & _xy ) : xy( _xy ) {}
    virtual ~Y();
};

template< typename T > struct X {
    static_assert( std::is_base_of<Y, T>::value, "T is not a Y" );
    T member_t;
    X() : member_t( *this ) {}
    virtual ~X();
}

struct DY : Y {
    int test2 = 2;
    void tester1 () {
        // int t1 = static_cast< X< DY > >( xy ).test1;
        // fails: no known conversion for argument 1 from 'X<Y>' to 'const X<DY>&'
    }
};

struct DX : X< DY > {
    int test1 = 1;
    void tester2 () {
        int t2 = member_t.test2; // perfectly ok, no problems.
    }
};

完整的错误列表是一个非常有意义的级联。我不明白的是如何处理tester1中的情况 - 一个要派生的类,在其成员之一的模板中使用自己,派生类必须在伴侣类模板(X - &gt; DX)。这是为了您的享受... ...(对不起,我的行号与此处格式略有不同)

main.cpp: In instantiation of 'struct X<Y>':
main.cpp:35:44:   required from here
main.cpp:23:5: error: static assertion failed: T is not a Y
     static_assert( std::is_base_of<Y, T>::value, "T is not a Y" );
     ^
main.cpp: In member function 'void DY::tester1()':
main.cpp:35:44: error: no matching function for call to 'X<DY>::X(X<Y>&)'
        int t1 = static_cast< X< DY > >( xy ).test1;
                                            ^
main.cpp:35:44: note: candidates are:
main.cpp:25:5: note: X<T>::X() [with T = DY]
     X ()
     ^
main.cpp:25:5: note:   candidate expects 0 arguments, 1 provided
main.cpp:21:31: note: constexpr X<DY>::X(const X<DY>&)
 template< typename T > struct X
                               ^
main.cpp:21:31: note:   no known conversion for argument 1 from 'X<Y>' to 'const X<DY>&'

我完全理解为什么X<Y>无法直接转换为X<DY> - 它们是无关的&#39;类。在我们知道事实的一般情况下,是否有一种优雅的方式来执行此转换YDY的基类?

我现在的猜测是根据编译器注释之一实现构造函数X<DY>::X( X<Y> )(或类似的运算符),但如果因任何原因Y无法复制,则可能无法实现...所以X<DY>::member_y这种方式必须从某些X<Y>::member_y复制,还是可以优雅地静态演员?不确定......

目标

有两个类XY,它们具有X将接受Y或其衍生物作为模板参数的关系。例如,这可以协调Y的常见行为 - 就像某个容器X中的对象一样。

使用派生的YX是不言而喻的(无论如何)我该怎么做。挑战在于拥有协调的行为&#39;本身可扩展。以上是尝试通过创建派生的XDX)来实现这一点,如果我们需要从派生的{{1引用X - 类型,这显然不起作用}} - 型

1 个答案:

答案 0 :(得分:1)

我们说你有:

struct A {};
struct B : A {};

template <typename T> struct Foo {};

int main()
{
   A a;
   B b;

   A& aRef = b;  // OK

   Foo<A> foo_a;
   Foo<B> foo_b;

   Foo<A>& foo_aRef = foo_b; // Not OK.
}

BA的子类型。这不会使Foo<B>成为Foo<A>的子类型。

你在行中看到的问题:

  int t1 = static_cast< X< DY > >( xy ).test1;

更糟糕。

xy的类型为X<Y>。您正尝试将其投放到X<DY>

这类似于尝试在我的示例代码中将Foo<A>转换为Foo<B>

我无法提出修正建议,因为我不清楚你在课程中尝试完成的任务。