0

I am new to cpp, coming from Java, so please be patient. I am trying to get the cereal library to work on a very basic test program before I add it into a larger program I am working on for fun. I am trying to serialize to json a Weather object, containing a string and an int.

hpp file:

#pragma once
using namespace std;
#include <iostream>

#include <cereal/archives/json.hpp>
#include <cereal/types/string.hpp>

class Weather
{
public:
    Weather(string status, int temp);

    
private:
    string status; 
    int temp;

    friend class cereal::access;
    template<class Archive>
    void serialize(Archive& archive);

};

cpp file:

#include "weather.h"

Weather::Weather(string status, int temp) {
    this->status = status;
    this->temp = temp;
}

template<class Archive>
void Weather::serialize(Archive& archive) {
    archive(CEREAL_NVP(this->temp),
            CEREAL_NVP(this->status)
    );
}

This object is called directly by main.

#include "main.h"
#include "weather.h"

#include <cereal/archives/json.hpp>
#include <fstream>

#include <iostream>
int main() {
    std::cout << "here";

    Weather today("clear", 10);

    std::ofstream os("data.json");
    cereal::JSONOutputArchive archive(os);

    {
        archive(CEREAL_NVP(today));
    }
}

I receive the following error on compile only:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "private: void __cdecl Weather::serialize<class cereal::JSONOutputArchive>(class cereal::JSONOutputArchive &)" (??$serialize@VJSONOutputArchive@cereal@@@Weather@@AEAAXAEAVJSONOutputArchive@cereal@@@Z) referenced in function "public: static void __cdecl cereal::access::member_serialize<class cereal::JSONOutputArchive,class Weather>(class cereal::JSONOutputArchive &,class Weather &)" (??$member_serialize@VJSONOutputArchive@cereal@@VWeather@@@access@cereal@@SAXAEAVJSONOutputArchive@1@AEAVWeather@@@Z)   Serialize   C:\Users\97cwe\source\repos\Serialize\main.obj  1   

I can barely read the error, let alone make any sense of it. From what I have been able to read online about this error, it is something to with cereal not being able to find the serialize class. I don't know how to fix either.

Any help would be appreciated. Thank you

Collin
  • 73
  • 8
  • 2
    put the serialze method in the header file, inside the class, like shown in the quick start guide https://uscilab.github.io/cereal/quickstart.html – pm100 Apr 13 '22 at 00:40
  • 1
    An extension to the comment above. This happens as c++ does not create template code that is not used. When `weather.cpp` is compiiled `Weather::serialize` is never used so it won't get instantiated and when `main.cpp` is compiled it assumes that somewhere it is as it is declared but not defined. When the linker tries to find where it is instantiated it comes up empty handed. Read up on templates and how they work/why you put them in headers for more info. See: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – Lala5th Apr 13 '22 at 00:46
  • Also, although unrelated and not yet causing you any problems, see [Why is `using namespace std;` considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). This is especially harmful when used inside a header file. – heap underrun Apr 13 '22 at 02:34
  • thank you for your help regarding this, and the explanation why. I am still very new to all of this. Also, thank you for that namespace declaration bad practice component. Definitely prevented some headaches there. To future people, as stated, putting it in header has it work. – Collin Apr 14 '22 at 00:38

0 Answers0