Ошибка ссылки при доступе к статическому члену структуры внутри функции шаблона внутри значения nlohman::json, только когда оптимизация отключена
Название немного глоток, но это лучший способ описать проблему.
Во всяком случае, на код:
#include <nlohmann-json/json.hpp>
using json = nlohmann::json;
template <class T> json F()
{
return json { "x", T::X };
}
struct Foo { static const int X = 1; };
int main()
{
F<Foo>();
return 0;
}
Когда скомпилировано с g++ -o test test.cpp
, это дает следующую ошибку ссылки:
/tmp/ccv5h5IX.o: In function `nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> F<Foo>()':
test.cpp:(.text._Z1FI3FooEN8nlohmann10basic_jsonISt3mapSt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS1_14adl_serializerEEEv[_Z1FI3FooEN8nlohmann10basic_jsonISt3mapSt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS1_14adl_serializerEEEv]+0x2f): undefined reference to `Foo::X'
collect2: error: ld returned 1 exit status
Любопытно, что это скомпилируется абсолютно нормально с -O1
оптимизация включена!
Я понятия не имею, что здесь происходит. Я столкнулся с этой проблемой в реальном коде (это очень упрощенный пример).
Если я переписать шаблон функции следующим образом:
template <class T> json F()
{
const auto X = T::X;
return json { "x", X };
}
If теперь будет компилироваться, даже если оптимизация отключена.