-
-
Notifications
You must be signed in to change notification settings - Fork 7.2k
Description
Description
I was trying to use the library with std::pmr
support by replacing the internal containers with std::pmr::map
and std::pmr::vector
. Initially, I faced compilation errors because std::map
and std::pmr::map
have different template parameters (due to different allocators). To work around this, I created template aliases matching the expected signature, which allowed the code to compile.
However, when I tried adding values to the JSON object, I encountered a static assertion failure. After investigating, I found that basic_json
does not provide a constructor that accepts an allocator, unlike other standard containers. As a result, the internal PMR containers are default-constructed without a proper allocator, which causes allocator mismatch errors during compile operations like insertions.
This is a high-priority issue
Reproduction steps
Just compile the attached minimal code example.
g++ -std=c++17 -o pmr_json pmr_json.cpp
Expected vs. actual results
Expected:
After configuring basic_json
with std::pmr
-compatible containers and strings, I expected to be able to construct and use JSON objects with custom memory resources (e.g., std::pmr::monotonic_buffer_resource
) without errors. Specifically, I expected that:
- Allocator-aware containers inside
basic_json
would receive the suppliedstd::pmr::polymorphic_allocator
. - Operations like assignment (
obj["key"] = value
) would work as with the defaultbasic_json
, but using the custom allocator.
Actual:
- While compilation succeeded with compatible template aliases, runtime operations on the JSON object failed with a static assertion or allocator mismatch errors.
- The root cause is that
basic_json
does not propagate the allocator to internal containers. It default-constructs internal members (e.g.,map
,vector
,string
) without using the providedpolymorphic_allocator
, leading to static assertion.
Note:
PMR support would be very helpful for controlling memory usage more precisely, especially in performance-critical or embedded applications. Having a clear path or official support for std::pmr
with basic_json
would make integration much smoother.
Minimal code example
#include <iostream>
#include <memory_resource>
#include <nlohmann/json.hpp>
// Template alias to pass polymorphic allocators to nlohmann::json
#if 1
template<typename Key, typename T, typename Ignored, typename Allocator>
using pmr_compatible_map = std::map<Key, T, std::less<Key>, Allocator>;
template<typename T, typename Allocator>
using pmr_compatible_vector = std::vector<T, Allocator>;
using pmr_string = std::basic_string<char, std::char_traits<char>, std::pmr::polymorphic_allocator<char>>;
#endif
using json_pmr = nlohmann::basic_json<
pmr_compatible_map,
pmr_compatible_vector,
pmr_string,
bool,
int64_t,
uint64_t,
double,
std::pmr::polymorphic_allocator>;
int main()
{
std::pmr::monotonic_buffer_resource arena(10240);
std::pmr::polymorphic_allocator<char> alloc(&arena);
// Create a polymorphic string using the allocator
pmr_string str(alloc);
str = "Hello, PMR world!";
std::cout << str << std::endl;
json_pmr obj;
obj["name"] = "Ankit Ghevariya"; // ❌ Static assertion failure here: no allocator was passed to the object
return 0;
}
Error messages
Note: The full error message is quite large, so I'm not pasting it here. I've attached a screenshot showing the last lines of the error output for reference.
Compiler and operating system
- OS: Ubuntu 24.04.2 LTS
- Compiler: GCC 13.3.0 (
g++ (Ubuntu 13.3.0-6ubuntu2~24.04)
) - C++ Standard: C++17 (
-std=c++17
)
Library version
- nlohmann/json version: 3.12.0
Validation
- The bug also occurs if the latest version from the
develop
branch is used. - I can successfully compile and run the unit tests.