Я пытаюсь специализировать шаблон сериализации boost для общего указателя на объекты с определенным базовым классом, используя boost 1.58, gcc 5.4 в режиме c ++ 14. Я считаю, что у меня есть правильная настройка SFINAE, чтобы специализировать функцию, но компилятор не выберет функцию, как я ожидаю.
#include <memory>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
class Artifact {
public:
Artifact() {}
virtual ~Artifact() {} // make polymorphic
};
class TestArtifact: public Artifact {
public:
TestArtifact() : Artifact() {}
};
namespace boost {
namespace serialization {
template <class Archive, class T>
void serialize(Archive &ar,
std::shared_ptr<typename std::enable_if<std::is_base_of<Artifact,T>::value,T>::type>& artifact,
//std::shared_ptr<T>& artifact,
unsigned int version) {
// save common Artifact structure on save ...
// Use factory to create specific Artifact (like TestArtifact) shared pointer
// from common Artifact info on load
}
}
}
int main(int argc, char** argv) {
auto t = std::make_shared<TestArtifact>();
std::cout << typeid(std::shared_ptr<TestArtifact>).name() << std::endl;
std::cout << typeid(std::shared_ptr<typename std::enable_if<std::is_base_of<Artifact,TestArtifact>::value,TestArtifact>::type>).name() << std::endl;
std::ofstream ofs(argv[1]);
boost::archive::binary_oarchive ar(ofs);
ar << t;
}
Когда я собираю этот код (с g ++ -std = c ++ 14 -o test_template test_template.cpp -lboost_system -lboost_serialization), я получаю следующую ошибку (после обычного почти бесконечного списка «требуемых из»),
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class std::shared_ptr<TestArtifact>’ has no member named ‘serialize’
t.serialize(ar, file_version);
Это говорит о том, что я не правильно настраиваю SFINAE. Когда я переставляю закомментированную строку, чтобы специализироваться на std::shared_ptr<T>
, код собирается и запускается, как и ожидалось, но я не хочу топать стандартную специализацию сериализации стандартного общего указателя boost. Когда я работаю с чрезмерно общей специализацией и печатаю идентификатор типа std::shared_ptr<TestArtifact>
и вывод класса SFINAE, они совпадают (с этим компилятором я получаю вывод
St10shared_ptrI12TestArtifactE
для обоих), поэтому я не понимаю, почему моя функция сериализации SFINAE не распознается.