当我尝试在 C++ 中使用谷物进行序列化时,出现了一个奇怪的错误

I'm getting a strange error when I try to do serialization with cereal in C++

我一直收到这个奇怪的错误

/usr/bin/ld: CMakeFiles/libdungeon.dir/src/main.cpp.o: in function `decltype (({parm#2}.serialize)({parm#1})) cereal::access::member_serialize<cereal::BinaryOutputArchive, Character>(cereal
::BinaryOutputArchive&, Character&)':
main.cpp:(.text._ZN6cereal6access16member_serializeINS_19BinaryOutputArchiveE9CharacterEEDTcldtfp0_9serializefp_EERT_RT0_[_ZN6cereal6access16member_serializeINS_19BinaryOutputArchiveE9Chara
cterEEDTcldtfp0_9serializefp_EERT_RT0_]+0x1f): undefined reference to `void Character::serialize<cereal::BinaryOutputArchive>(cereal::BinaryOutputArchive&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/libdungeon.dir/build.make:119: bin/libdungeon] Error 1
make[1]: *** [CMakeFiles/Makefile2:96: CMakeFiles/libdungeon.dir/all] Error 2
make: *** [Makefile:104: all] Error 2

我做了 类 超级准系统,但我仍然遇到错误。

character.hpp:

#pragma once

#include <string>

#include <cereal/archives/binary.hpp>

  class Character {

    public:

      Character(int t_level);

    private:

      friend class cereal::access;

      template <class Archive>
      void serialize(Archive & ar);

      int m_level = 0;

  };

character.cpp:

#include "character.hpp"

using namespace std;

  //Generic constructor
  Character::Character(int t_level){

    m_level = t_level;

  }


  template<class Archive>
  void Character::serialize(Archive & ar) {
    ar (m_level);
    }

main.cpp:


#include "character.hpp"
#include <fstream>
#include <cereal/archives/binary.hpp>

using namespace std;
int main() {
  Character test = Character(5);

  std::ofstream ofs("archive", std::ios::binary);
  cereal::BinaryOutputArchive archive(ofs);

  archive(test);

  return 0;

}

CMakeLists.txt:

# Basic setup
cmake_minimum_required(VERSION 3.5)
project (libdungeon LANGUAGES CXX VERSION 0.0.1)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# Directories with header files
include_directories ("include")

# Setting compile flags
SET(GCC_COVERAGE_COMPILE_FLAGS "-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wpedantic")
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

#conan
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

# Libraries
add_executable(libdungeon src/character.cpp src/main.cpp)

target_link_libraries(libdungeon ${CONAN_LIBS})

有什么想法吗?当我使用类似此处 https://uscilab.github.io/cereal/stl_support.html 的示例文件和类似的 cmake 文件时,一切正常。

您不能将函数模板的声明和定义分离到 C++ 中的头文件 (.h) 和实现文件 (.cpp)。要修复,请将 Character::serialize 的函数模板定义移至头文件:

//in character.hpp

...

template <class Archive>
void serialize(Archive & ar){ //function definition moved to header file
    ar (m_level);
}

...

这是 C++ 中模板的重大限制。请参阅此答案以更全面地解释为什么函数模板定义必须在头文件中: