Date: Mon, 17 Mar 2025 19:29:18 +0000
On Mon, 17 Mar 2025, 13:13 Donald Duck via Std-Proposals, <
std-proposals_at_[hidden]> wrote:
> Some libraries such as https://github.com/nlohmann/json have classes
> which are in fact typedefs for very complicated types, for example:
>
> template<template<typename U, typename V, typename... Args> class
>> ObjectType =
>> std::map,
>> template<typename U, typename... Args> class ArrayType =
>> std::vector,
>> class StringType = std::string, class BooleanType = bool,
>> class NumberIntegerType = std::int64_t,
>> class NumberUnsignedType = std::uint64_t,
>> class NumberFloatType = double,
>> template<typename U> class AllocatorType = std::allocator,
>> template<typename T, typename SFINAE = void> class
>> JSONSerializer =
>> adl_serializer,
>> class BinaryType = std::vector<std::uint8_t>,
>> class CustomBaseClass = void>
>> class basic_json;
>>
> using json = basic_json<>;
>
>
> I would like to forward declare their json class like this:
>
> class json;
>
>
> The problem is that if I try doing this, I get the following error:
>
> nlohmann/json.hpp: error: conflicting declaration ‘using json = class
>> basic_json<>’
>>
> main.cpp: note: previous declaration as ‘class json’
>
>
> I don't see why this should be an error. class json; declares an
> incomplete type called json and I can't access its members, instantiate it,
> etc anyway unless I include its definition. So it shouldn't matter if it's
> a class, a typedef for a class, or even a typedef for a primitive.
>
It does matter though. If you don't know whether it's a class or a built-in
type then the compiler doesn't know whether int (json::*)() is a valid
type. What if it is really a typedef for a pointer? Or a reference? Or int?
Is json* a valid type? What if it is a typedef for X& or int()const ?
Also in theory the size and representation of json* could depend on whether
it's a class type or not, although in practice it doesn't matter for any of
the major implementations.
> So I suggest that class json; simply means that I'm forward declaring an
> incomplete type that can be anything, instead of meaning that it *must*
> be a class (as opposed to a typedef for a class). Alternatively, a new
> syntax such as typename json; could also work, as long as I don't need to
> copy the entire declaration for their complicated template.
>
The library you want to use could provide you with a header that has the
correct forward declaration and typedef.
std-proposals_at_[hidden]> wrote:
> Some libraries such as https://github.com/nlohmann/json have classes
> which are in fact typedefs for very complicated types, for example:
>
> template<template<typename U, typename V, typename... Args> class
>> ObjectType =
>> std::map,
>> template<typename U, typename... Args> class ArrayType =
>> std::vector,
>> class StringType = std::string, class BooleanType = bool,
>> class NumberIntegerType = std::int64_t,
>> class NumberUnsignedType = std::uint64_t,
>> class NumberFloatType = double,
>> template<typename U> class AllocatorType = std::allocator,
>> template<typename T, typename SFINAE = void> class
>> JSONSerializer =
>> adl_serializer,
>> class BinaryType = std::vector<std::uint8_t>,
>> class CustomBaseClass = void>
>> class basic_json;
>>
> using json = basic_json<>;
>
>
> I would like to forward declare their json class like this:
>
> class json;
>
>
> The problem is that if I try doing this, I get the following error:
>
> nlohmann/json.hpp: error: conflicting declaration ‘using json = class
>> basic_json<>’
>>
> main.cpp: note: previous declaration as ‘class json’
>
>
> I don't see why this should be an error. class json; declares an
> incomplete type called json and I can't access its members, instantiate it,
> etc anyway unless I include its definition. So it shouldn't matter if it's
> a class, a typedef for a class, or even a typedef for a primitive.
>
It does matter though. If you don't know whether it's a class or a built-in
type then the compiler doesn't know whether int (json::*)() is a valid
type. What if it is really a typedef for a pointer? Or a reference? Or int?
Is json* a valid type? What if it is a typedef for X& or int()const ?
Also in theory the size and representation of json* could depend on whether
it's a class type or not, although in practice it doesn't matter for any of
the major implementations.
> So I suggest that class json; simply means that I'm forward declaring an
> incomplete type that can be anything, instead of meaning that it *must*
> be a class (as opposed to a typedef for a class). Alternatively, a new
> syntax such as typename json; could also work, as long as I don't need to
> copy the entire declaration for their complicated template.
>
The library you want to use could provide you with a header that has the
correct forward declaration and typedef.
Received on 2025-03-17 19:29:36