Шаблон класса C++ определенного базового класса

sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix version

45
задан Peter Mortensen 23 January 2010 в 18:14
поделиться

6 ответов

Точнее:

class B {};
class D1 : public B {};
class D2 : public B {};
class U {};

template <class X, class Y> class P {
    X x;
    Y y;
public:
    P() {
        (void)static_cast<B*>((X*)0);
        (void)static_cast<B*>((Y*)0);
    }
};

int main() {
    P<D1, D2> ok;
    P<U, U> nok; //error
}
12
ответ дан 26 November 2019 в 21:22
поделиться

Это был отличный вопрос! Исследуя это через эту ссылку , я пришел к следующему, которое, по общему признанию, не сильно отличается от предоставленного там решения. Узнай что-нибудь каждый день ... проверяй!

#include <iostream>
#include <string>
#include <boost/static_assert.hpp>

using namespace std;

template<typename D, typename B>
class IsDerivedFrom
{
  class No { };
  class Yes { No no[3]; };

  static Yes Test(B*); // declared, but not defined
  static No Test(...); // declared, but not defined

public:
  enum { IsDerived = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
};


class Base
{
public:
    virtual ~Base() {};
};

class A : public Base
{
    int i;
};

class B : public Base
{
    bool b;
};

class C
{
    string z;
};


template <class T1, class T2>
class BasePair
{
public:
    BasePair(T1 first, T2 second)
        :m_first(first),
         m_second(second)
    {
        typedef IsDerivedFrom<T1, Base> testFirst;
        typedef IsDerivedFrom<T2, Base> testSecond;

        // Compile time check do...
        BOOST_STATIC_ASSERT(testFirst::IsDerived == true);
        BOOST_STATIC_ASSERT(testSecond::IsDerived == true);

        // For runtime check do..
        if (!testFirst::IsDerived)
            cout << "\tFirst is NOT Derived!\n";
        if (!testSecond::IsDerived)
            cout << "\tSecond is NOT derived!\n";

    }

private:
    T1 m_first;
    T2 m_second;
};


int main(int argc, char *argv[])
{
    A a;
    B b;
    C c;

    cout << "Creating GOOD pair\n";
    BasePair<A, B> good(a, b);

    cout << "Creating BAD pair\n";
    BasePair<C, B> bad(c, b);
    return 1;
}
2
ответ дан RC. 26 November 2019 в 21:22
поделиться

В ответе, предложенном неизвестным(yahoo), на самом деле не требуется иметь в качестве членов переменные типа X и Y. Этих строк достаточно в конструкторе:

static_cast<B*>((X*)0);
static_cast<B*>((Y*)0);
0
ответ дан 26 November 2019 в 21:22
поделиться
class B
{
};
class D : public B
{
};
class U
{
};

template <class X, class Y> class P
{
    X x;
    Y y;
public:
    P()
    {
        (void)static_cast<X*>((Y*)0);
    }
};
0
ответ дан 26 November 2019 в 21:22
поделиться

C++ еще не позволяет это напрямую. Вы можете реализовать это косвенно, используя STATIC_ASSERT и тип проверки внутри класса:

template < typename T1, typename T2 >
class BasePair{
    BOOST_STATIC_ASSERT(boost::is_base_of<Base, T1>);
    BOOST_STATIC_ASSERT(boost::is_base_of<Base, T2>);
    T1 first;
    T2 second;
};
9
ответ дан 26 November 2019 в 21:22
поделиться

Сначала исправьте объявление

template < class T1, class T2 >
class BasePair{
    T1 first;
    T2 second;
};

Затем, вы можете объявить в базовом классе какую-нибудь закрытую функцию Foo(); и сказать базовому классу, чтобы BasePair была другом; затем в конструкторе-друге вам просто нужно вызвать эту функцию. Таким образом Вы получите ошибку во время компиляции, когда кто-то попытается использовать другие классы в качестве параметров шаблона.

0
ответ дан 26 November 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: