2010-09-14 5 views
1

У меня есть класс «генератор», который в основном создает свой подкласс. Чтобы использовать эту вещь, я просто подклассифицирую ее и передаю ей правильные параметры для построения объекта, который я хочу построить. Я хочу сериализовать эти вещи, и нет никаких оснований делать это для каждого подкласса, поскольку все данные находятся в базе. Вот что у меня есть пример:boost.serialization - бесплатная версия и реализация базового класса

#include <boost/serialization/serialization.hpp> 
template < typename T > 
struct test_base 
{ 
    // works... 
    //template < typename Archive > 
    //void serialize(Archive &, unsigned int const) 
// { 
    //} 
}; 

template < typename T > 
void f(test_base<T> const&) {} 

struct test_derived : test_base<int> 
{ 
}; 

namespace boost { namespace serialization { 

template < typename Archive, typename T > 
void serialize(Archive &, test_base<T> &, unsigned int const) 
{ 
} 

}} 

#include <boost/archive/binary_oarchive.hpp> 
#include <sstream> 
int main() 
{ 
    int x = 5; 
    test_derived d; 
    //boost::serialization::serialize(x, d, 54); // <- works. 

    std::ostringstream str; 
    boost::archive::binary_oarchive out(str); 
    out & d; // no worky. 
} 

Я хочу, чтобы бесплатная версия работала, если это возможно. Это?

Version above pukes up error about serialize, не являющийся членом test_derived.

ответ

0

Уточнение, почему возникает проблема:
boost :: serialization имеет способы реализации функции сериализации. Как метод класса или (в вашем случае) неинтрузивный способ определения функции в пространстве имен boost :: serialization.
Итак, компилятор должен как-то решить, какую реализацию выбрать. По этой причине boost имеет «стандартную» реализацию функции boost :: serialization :: serialize template.
Подпись:

template<class Archive, class T> 
inline void serialize(Archive & ar, T & t, const BOOST_PFTO unsigned int file_version) 


В этой функции есть вызов T :: сериализации (...). Поэтому, когда вам не нужна интуитивная версия, вы должны переопределить функцию boost :: serialization :: serialize с чем-то более явным, чем шаблон-функция по умолчанию.
Теперь проблема:
В вашем случае компилятор должен решить, если он
а) выбирает вариант, когда параметр должен быть с приведением неявным (test_derived & к test_base &)
б) использовать общую функцию без литья (Т test_derived &)
Вы хотите, чтобы компилятор использовать вариант а), но компилятор предпочитает б)

решение:
Я не знаю, действительно хорошее решение. Я думаю, я бы пошел с макросом, который генерирует реализации сериализации (...) с явным типом.
Если это не возможно для вас решение, вы могли бы также сказать компилятору более четко, как назвать:

out & *((test_base<int>*)&d); 


и завернуть его в некоторой вспомогательной функции (потому что никто не хочет смотреть на такой код весь день)

Я надеюсь, что это четкое описание и помогает

В случае мое объяснение не было ясно, вот пример:

#include <iostream> 
class Base 
{ 
public: 
    virtual ~Base() 
    { 
    } 
}; 

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


void foo(Base& bar) 
{ 
    std::cout << "special" << std::endl; 
} 

template<typename T> 
void foo(T& bar) 
{ 
    std::cout << "generic" << std::endl; 
} 

int main() 
{ 
    Derived derived; 
    foo(derived);   // => call to generic implementation 
    foo(*((Base*) &bla)); // => call to special 
    return 0; 
} 
Смежные вопросы