title: C++ sidebar_position: 5 id: cpp license: | Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
C++ output is one header per schema file, for example:
<cpp_out>/addressbook.hMessages generate final classes with typed accessors and byte helpers:
class Person final { public: class PhoneNumber final { public: const std::string& number() const; std::string* mutable_number(); template <class Arg, class... Args> void set_number(Arg&& arg, Args&&... args); fory::Result<std::vector<uint8_t>, fory::Error> to_bytes() const; static fory::Result<PhoneNumber, fory::Error> from_bytes( const uint8_t* data, std::size_t size); static fory::Result<PhoneNumber, fory::Error> from_bytes(const std::vector<uint8_t>& data); }; const std::string& name() const; std::string* mutable_name(); template <class Arg, class... Args> void set_name(Arg&& arg, Args&&... args); const Animal& pet() const; Animal* mutable_pet(); };
Optional message fields generate has_xxx, mutable_xxx, and clear_xxx APIs:
class Envelope final { public: bool has_payload() const { return payload_ != nullptr; } const Envelope::Payload& payload() const { return *payload_; } Envelope::Payload* mutable_payload() { if (!payload_) { payload_ = std::make_unique<Envelope::Payload>(); } return payload_.get(); } void clear_payload() { payload_.reset(); } private: std::unique_ptr<Envelope::Payload> payload_; };
Unions generate std::variant wrappers:
class Animal final { public: enum class AnimalCase : uint32_t { DOG = 1, CAT = 2, }; static Animal dog(Dog v); static Animal cat(Cat v); AnimalCase animal_case() const noexcept; uint32_t animal_case_id() const noexcept; bool is_dog() const noexcept; const Dog* as_dog() const noexcept; Dog* as_dog() noexcept; const Dog& dog() const; Dog& dog(); template <class Visitor> decltype(auto) visit(Visitor&& vis) const; private: std::variant<Dog, Cat> value_; };
Generated headers include FORY_UNION, FORY_ENUM, and FORY_STRUCT macros for serialization metadata. Field and payload configuration is embedded in the generated FORY_STRUCT/FORY_UNION entries.
Generated registration function:
inline void register_types(fory::serialization::BaseFory& fory) { fory.register_union<Animal>(106); fory.register_enum<Person::PhoneType>(101); fory.register_struct<Person::PhoneNumber>(102); fory.register_struct<Person>(100); fory.register_struct<Dog>(104); fory.register_struct<Cat>(105); fory.register_struct<AddressBook>(103); }
For schemas without explicit [id=...], generated registration uses computed numeric IDs:
fory.register_enum<Status>(1124725126); fory.register_union<Wrapper>(1471345060); fory.register_struct<Envelope>(3022445236); fory.register_union<Envelope::Detail>(1609214087); fory.register_struct<Envelope::Payload>(2862577837);
If option enable_auto_type_id = false; is set:
fory.register_struct<Config>("myapp.models.Config"); fory.register_union<Holder>("myapp.models.Holder");
addressbook::Person person; person.set_name("Alice"); *person.mutable_pet() = addressbook::Animal::dog(addressbook::Dog{}); auto bytes = person.to_bytes(); auto restored = addressbook::Person::from_bytes(bytes.value());
With --grpc, C++ emits <stem>.service.h, <stem>.service.grpc.h, and <stem>.service.grpc.cc. The API header contains synchronous interfaces and route constants under ::<namespace>::service; the binding header contains generated grpc::SerializationTraits plus client and server wrappers under ::<namespace>::service::grpc. See C++ gRPC for build and usage guidance.