当我尝试在 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++ 中模板的重大限制。请参阅此答案以更全面地解释为什么函数模板定义必须在头文件中:
我一直收到这个奇怪的错误
/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++ 中模板的重大限制。请参阅此答案以更全面地解释为什么函数模板定义必须在头文件中: