LINUX.ORG.RU

100 dynamic_cast'ов за 1 миллисекунду

 ,


0

3
#include <iostream>
#include <typeinfo>
#include <sys/time.h>
#include <stdint.h>

using namespace std;


// Type Lists
template< typename T, T v = T() >
struct Value
{
    enum { val = v };
    typedef T value_type;
};

struct NullItem
{
    static void Print() { std::cout << std::endl; }
};

template< typename V, typename L >
struct List
{
    typedef V value_type;

    static void Print()
    {
        std::cout << value_type::val << ", ";
        L::Print();
    }
};

template< class List > struct Next;

template< class V, class L >
struct Next< List< V, L > >
{
    typedef L NextType;
};

template< unsigned n, int i = 0, int until = n + i, class G = NullItem >
class Generate
{
    typedef List< Value< int, i >, G > NewList;
public:
    typedef typename Generate< n, i + 1, until, NewList >::NextType NextType;
};

template< unsigned n, int until, class G >
class Generate<n, until, until, G>
{
public:
    typedef G NextType;
};


// Linear class hierarchy
struct IBase
{
    virtual ~IBase() {}
    virtual void Print() = 0;
};

template< class TList >
struct CRTP : CRTP< typename Next< TList >::NextType >
{
    virtual void Print()
    {
        cout << typeid( *this ).name() << " " << TList::value_type::val << endl;
    }
};

template<>
struct CRTP< NullItem > : IBase
{
    // IBase
    virtual void Print()
    {
        cout << typeid( *this ).name() << endl;
    }
};


void TestDownCast( IBase *b )
{
    static const int NUM_CASTS = 10 * 1000;

    struct timeval tvStart, tvEnd;
    gettimeofday( &tvStart, NULL );

    for( int i = 0; i < NUM_CASTS; ++i )
    {
        CRTP< NullItem > *pCRTP = dynamic_cast< CRTP< NullItem > * >( b );
        /*if ( pCRTP )
        {
            cout << "downcasted successfully" << endl;
        }*/
    }

    gettimeofday( &tvEnd, NULL );
    int64_t elapsed = (int64_t)( tvEnd.tv_sec - tvStart.tv_sec ) * 1000000 +
                               ( tvEnd.tv_usec - tvStart.tv_usec );

    cout << NUM_CASTS << " casts : elapsed " << elapsed << " us" << endl;
}


int main()
{
    static const int NUM_ITEMS = 500;
    typedef Generate< NUM_ITEMS >::NextType GenList;
    //GenList::Print();

    CRTP< GenList > r;
    //r.Print();

    TestDownCast( &r );

    return 0;
}
g++ dc.cpp -o dc
./dc
10000 casts : elapsed 97958 us

Не «ШОК!ФОТО!» ли это?



Последнее исправление: nerdogeek (всего исправлений: 2)

Ответ на: комментарий от no-such-file

Какая разница, где лежит объект? Да хоть void*! У объекта есть указатель на vtbl, который можно сравнить с эталонным.

k_andy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.