invalid use of incomplete type (boost::optional) / compile error
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 50.6k
- Forks
- 7.5k
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 58
Description
Description
Hi there,
I get some compiler errors, which I unfortunately don't understand in detail. See the small minimal example. Probably it's a compiler bug, because it compiles with gcc 11+ and clang11. It also compiles with gcc 10 when using -std=c++17.
The code also compiles fine, if I comment out the "to_json" function or make the Dummy constructor non-explicit. I don't understand why in the gcc10 setup with c++11 standard, the to_json function gets inspected at all. How can it matter if this function exists or not?
Thank you for your comments!
Reproduction steps
See also https://godbolt.org/z/1Whjn8nKn
Expected vs. actual results
It should compile, but it doesn't.
Minimal code example
#include <boost/optional.hpp>
#include <nlohmann/json.hpp>
class Dummy {
explicit Dummy(const nlohmann::json& data) {
}
};
class Holder {
boost::optional<Dummy> d;
public:
};
void to_json(nlohmann::json& j, const Holder& h) {
}
int main(int argc, char* argv[]) {
Holder h;
return 0;
}
Error messages
In file included from <source>:3:
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp: In substitution of 'template<class Expected, template<class ...> class Op, class ... Args> using is_detected_exact = std::is_same<Expected, typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, Op, Args ...>::type> [with Expected = void; Op = nlohmann::detail::to_json_function; Args = {nlohmann::adl_serializer<Dummy, void>, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long int, long unsigned int, double, std::allocator, nlohmann::adl_serializer>&, Dummy}]':
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:986:13: required from 'constexpr const bool nlohmann::detail::has_to_json<nlohmann::basic_json<>, Dummy, void>::value'
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:1204:53: required from 'constexpr const bool nlohmann::detail::is_compatible_type_impl<nlohmann::basic_json<>, Dummy, void>::value'
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:14016:55: required by substitution of 'template<class CompatibleType, class U, typename std::enable_if<((! nlohmann::detail::is_basic_json<T>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<>, U>::value), int>::type <anonymous> > nlohmann::basic_json<>::basic_json(CompatibleType&&) [with CompatibleType = Dummy; U = Dummy; typename std::enable_if<((! nlohmann::detail::is_basic_json<T>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<>, U>::value), int>::type <anonymous> = <missing>]'
/opt/compiler-explorer/libs/boost_1_79_0/boost/type_traits/is_constructible.hpp:37:65: required by substitution of 'template<class T, class Arg, class> static boost::type_traits::yes_type boost::detail::is_constructible_imp::test1(int) [with T = Dummy; Arg = Dummy; <template-parameter-1-3> = <missing>]'
/opt/compiler-explorer/libs/boost_1_79_0/boost/type_traits/is_constructible.hpp:54:185: required from 'struct boost::is_constructible<Dummy, Dummy>'
/opt/compiler-explorer/libs/boost_1_79_0/boost/optional/optional.hpp:816:8: [ skipping 10 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:14016:55: required by substitution of 'template<class CompatibleType, class U, typename std::enable_if<((! nlohmann::detail::is_basic_json<T>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<>, U>::value), int>::type <anonymous> > nlohmann::basic_json<>::basic_json(CompatibleType&&) [with CompatibleType = const Dummy&; U = Dummy; typename std::enable_if<((! nlohmann::detail::is_basic_json<T>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<>, U>::value), int>::type <anonymous> = <missing>]'
/opt/compiler-explorer/libs/boost_1_79_0/boost/type_traits/is_constructible.hpp:37:65: required by substitution of 'template<class T, class Arg, class> static boost::type_traits::yes_type boost::detail::is_constructible_imp::test1(int) [with T = Dummy; Arg = const Dummy&; <template-parameter-1-3> = <missing>]'
/opt/compiler-explorer/libs/boost_1_79_0/boost/type_traits/is_constructible.hpp:54:185: required from 'struct boost::is_constructible<Dummy, const Dummy&>'
/opt/compiler-explorer/libs/boost_1_79_0/boost/optional/optional.hpp:816:8: required from 'struct boost::optional_detail::is_optional_constructible<Dummy, const Dummy&>'
/opt/compiler-explorer/libs/boost_1_79_0/boost/core/enable_if.hpp:41:10: required from 'struct boost::enable_if<boost::optional_detail::is_optional_constructible<Dummy, const Dummy&>, bool>'
/opt/compiler-explorer/libs/boost_1_79_0/boost/optional/optional.hpp:964:14: required by substitution of 'template<class U> boost::optional<Dummy>::optional(const boost::optional<T>&, typename boost::enable_if<boost::optional_detail::is_optional_constructible<Dummy, const U&>, bool>::type) [with U = Dummy]'
<source>:20:12: required from here
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:802:7: error: invalid use of incomplete type 'struct nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::to_json_function, nlohmann::adl_serializer<Dummy, void>, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long int, long unsigned int, double, std::allocator, nlohmann::adl_serializer>&, Dummy>'
802 | using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
| ^~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/nlohmann_json/v3.6.0/single_include/nlohmann/json.hpp:776:8: note: declaration of 'struct nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::to_json_function, nlohmann::adl_serializer<Dummy, void>, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long int, long unsigned int, double, std::allocator, nlohmann::adl_serializer>&, Dummy>'
776 | struct detector
| ^~~~~~~~
Compiler returned: 1
Compiler and operating system
gcc 10, linux,
Library version
3.10.3
Validation
- The bug also occurs if the latest version from the
developbranch is used. - I can successfully compile and run the unit tests.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the minimal example from the issue with GCC 10 in C++11, using boost::optional and nlohmann/json.hpp, then compare it with GCC 11+, Clang 11, and C++17. Use the Compiler Explorer example and the reported template-instantiation trace to identify why to_json triggers the incomplete-type error; done means the example compiles without requiring a non-explicit Dummy constructor.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100