访问nlohmann json的静态函数



我想为nlohmann json库创建一个类包装器。因此,我创建了一个带有静态变量nlohmann::json和静态函数的类来访问它。但是当我编译它时,编译器显示无法解析的外部符号:

unresolved external symbol "private: static class nlohmann::json_abi_v3_11_2::basic_json<class std::map,class std::vector,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool,__int64,unsigned __int64,double,class std::allocator,struct nlohmann::json_abi_v3_11_2::adl_serializer,class std::vector<unsigned char,class std::allocator<unsigned char> > > Config::data"

下面是我的代码:
#pragma once
#include <string>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <nlohmann/json.hpp>
/**
* @brief Class giving access to the settings of the application.
* 
* This class contains static methods that read configuration from file.
* Only works on Windows OS.
* 
* 
*/
class Config
{
private:
static constexpr const char* path = "Test\PIDController";
static constexpr const char* filename = "config.txt";
static nlohmann::json data;
public:
/**
* @brief Check if config exists. If not, create it. Then load config.
* 
* Check if the directory of the config file exists. If not, create it.
* Then check if the config file exists. If not, create it with default
* configuration.
* 
* Use JSON format to store data using JSON for modern C++.
* [https://github.com/nlohmann/json](https://github.com/nlohmann/json)
* 
*/
static void check_default_conf()
{
std::filesystem::path file_path = std::filesystem::path(getenv("appdata")) / std::filesystem::path(path) / std::filesystem::path(filename);
if (!std::filesystem::is_directory(path) || !std::filesystem::exists(file_path))
{
bool a = std::filesystem::create_directories(std::filesystem::path(getenv("appdata")) / std::filesystem::path(path));
std::ofstream of(file_path);
nlohmann::json default_conf;
default_conf["target"] = 1e-3f;
of << std::setw(4) << default_conf;
of.close();
}
// Load conf file
std::ifstream f(file_path);
data << f;
f.close();
}
/**
* @brief Save config file.
* 
*/
static void save_conf()
{
std::filesystem::path file_path = std::filesystem::path(getenv("appdata")) / std::filesystem::path(path) / std::filesystem::path(filename);
std::ofstream ofs(file_path);
ofs << std::setw(4) << data;
ofs.close();
}
/**
* @brief Get setting matching the given key.
* 
* @tparam T Setting type
* @param key Setting key
* @return Value of the entry
*/
template <typename T>
static T get(const char* key)
{
return data[key].get<T>();
}
/**
* @brief Set setting matching the given key.
* 
* @tparam T Setting type
* @param key Setting key
* @param value Value to set
* 
* @par Returns
*      Nothings.
*/
template <typename T>
static void set(const char* key, T value)
{
data[key] = value;
}
};

你知道问题在哪里吗?我认为我的代码有一个糟糕的模式,但我不明白在哪里。

我使用Visual c++ 2022和c++ 20。

在静态成员文档中可以看到,Config类中的这一行:

class Config
{
// ...
static nlohmann::json data;    //  <---
// ...
};

声明而不是定义.

为了解决这个问题,需要添加一个定义在其中一个cpp文件中(如果存在,最好是Config.cpp):

nlohmann::json Config::data;

自c++17以来,有一个替代方案:您可以将data定义为Config类中的inline static成员变量(不需要额外的定义):

class Config
{
// ...
inline static nlohmann::json data;
// ...
};

最新更新