3

I have a class where I want to have a function that uses nlohmann::json& as the argument:

class MyClass
{
public:
    void foo(nlohmann::json& node); 
};

But I don't want to include the json.hpp file in my header, just my .cpp. How can I declare the nlohmann::json in the header? I tried:

namespace nlohmann
{
    class json;
}

But that doesn't seem to work.

Justin
  • 24,288
  • 12
  • 92
  • 142
Chip Burwell
  • 423
  • 3
  • 10

2 Answers2

5

If we have a look at the source, we can see that json is defined in json_fwd.hpp.

using json = basic_json<>;

json is an alias for basic_json so you need to forward declare basic_json before you can declare json. If you scroll up a bit in json_fwd.hpp, you'll see the massive forward declaration for basic_json. So if you want to use nlohmann::json & in a header file, you can include json_fwd.hpp.

Indiana Kernick
  • 5,041
  • 2
  • 20
  • 50
  • Is there a way to do this without including json_fwd.hpp? – Chip Burwell Apr 07 '21 at 00:29
  • 2
    @ChipBurwell Yes, you can copy-and-paste the contents of `json_fwd.hpp` but that's what `#include` does (and I wouldn't recommend doing that). The `json_fwd.hpp` header is created exactly for this purpose, forwarding `json` without including the gigantic `json.hpp` header. – Indiana Kernick Apr 07 '21 at 00:31
0

Please advise what is wrong with my case that does not work.

I have a extracted this minimal example to show the issue: in my project folder (name is 'ttt'):

ttt$ ls
config.cpp  include  main.cpp


ttt$ ls include/
config.h  nlohmann

ls include/nlohmann/
json.hpp  json_fwd.hpp <<<<<These are copied from the 3.11.2 https://github.com/nlohmann/json/releases/tag/v3.11.2


ttt$ cat main.cpp 
#include "config.h"
#include <iostream>

int main() {
  Config c("../global_config.json");
  std::cout << c.getParcelCount() << std::endl;
return 0;
}



ttt$ cat config.cpp 
#include <nlohmann/json.hpp>
#include "config.h"
#include <fstream>

Config::Config(std::string config_path) {
  std::ifstream f(config_path);
  config_ = json::parse(f);
}




ttt$ cat include/config.h 
#include <nlohmann/json_fwd.hpp>

using json = nlohmann::json;

class Config {
  private:
      json config_;

  public:
    Config(std::string path);
    int getParcelCount() {
      return config_.value("parcel_count", 3);
    }

};

Running with following command:

g++ config.cpp main.cpp -std=c++17 -I include/

I am getting following errors:

In file included from main.cpp:1:0:
include/config.h:7:9: error: field ‘config_’ has incomplete type ‘json {aka nlohmann::json_abi_v3_11_2::basic_json<>}’
    json config_;
         ^~~~~~~
In file included from include/config.h:1:0,
                 from main.cpp:1:
include/nlohmann/json_fwd.hpp:151:7: note: declaration of ‘using json = using json = class nlohmann::json_abi_v3_11_2::basic_json<> {aka class nlohmann::json_abi_v3_11_2::basic_json<>}’
 class basic_json;
       ^~~~~~~~~~

I am using g++ 7.5.0 version on Jetson Xavier NX with JetPack 4.6.3

g++ (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0

If more infor

Arsen
  • 654
  • 8
  • 20
  • You should probably ask a new question rather than piggy back onto this old question. Also, you don't show what config.h is, but the issue is probably in there. Does config.h #include "json_fwd.h" – Chip Burwell Aug 24 '23 at 16:03
  • You are right, I should have opened a new question. I will update this when I have a little more time than now, as I want to include some additional information that needs more time to be spent. Thanks! – Arsen Sep 01 '23 at 15:42