Hi. I'm modernizing some code, to use std::variant instead of ad-hoc
peudo-variant structs.
These structs need to be encoded/decoded via avro::codec_traits
specializations, but given
that std::variant is variadic, I'm struggling a bit. I've done my research
and found peter's [1] and also looked at [2], which I thought might work,
but does not, and I don't understand the errors I'm getting with MSVC 2019
in C++17 mode.
The code is below, with also a subset of the compiler errors I'm getting.
[1]
https://www.reddit.com/r/cpp/comments/f8cbzs/creating_stdvariant_based_on_index_at_runtime/filw8g7?utm_source=share&utm_medium=web2x&context=3
[2]
https://www.boost.org/doc/libs/develop/libs/mp11/doc/html/mp11.html#mp_with_...
template <> struct codec_traitsstd::monostate {
static void encode(Encoder& e, const std::monostate&) {
e.encodeNull();
}
static void decode(Decoder& d, std::monostate&) {
d.decodeNull();
}
};
template struct codec_traits> {
static void encode(Encoder& e, const std::variant& var) {
e.encodeUnionIndex(var.index());
std::visit(
[&e](const auto& alternative) {
avro::encode(e, alternative);
},
var
);
}
static void decode(Decoder& d, std::variant& var) {
const size_t index = d.decodeUnionIndex();
if (index >= sizeof...(Ts)) {
throw avro::Exception("Invalid Union index");
}
auto& alternative =
boost::mp11::mp_with_index(
index,
[&var](auto I) {
return var.emplace<I>(); // I is mp_size_t<index>{} here
}
)
;
avro::decode(d, alternative);
}
};
1>Messages.cpp
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70,1):
error C2220: the following warning is treated as an error
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70,1):
warning C4239: nonstandard extension used: 'initializing': conversion from
'std::monostate' to 'std::monostate &'
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70,1):
message : A non-const reference may only be bound to an lvalue
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70):
message : while compiling class template member function 'void
avro::codec_traits<T>::decode(avro::Decoder
&,std::variantstd::monostate,int64_t,double &)'
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]
1>D:\pdgm\kits\trunk\Avrocpp\1.9.2-Boost-1.74.0\Win_x64_10_v16_debug\include\avro/Specific.hh(341):
message : see reference to function template instantiation 'void
avro::codec_traits<T>::decode(avro::Decoder
&,std::variantstd::monostate,int64_t,double &)' being compiled
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]
1>D:\pdgm\kits\trunk\Avrocpp\1.9.2-Boost-1.74.0\Win_x64_10_v16_debug\include\avro/Specific.hh(333):
message : see reference to class template instantiation
'avro::codec_traits<T>' being compiled
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\codegen/Messages.i.ipp(1527):
message : see reference to function template instantiation 'void
avro::encodepdgm::eml::etp12::Datatypes::IndexValue_item_v(avro::Encoder
&,const T &)' being compiled
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]
1>D:\pdgm\kits\trunk\boost\1.74.0\Win_x64_10_v16_debug\include\boost/mp11/detail/mp_with_index.hpp(87,1):
error C2440: 'return': cannot convert from '__int64' to 'std::monostate'
1>D:\pdgm\kits\trunk\boost\1.74.0\Win_x64_10_v16_debug\include\boost/mp11/detail/mp_with_index.hpp(87,1):
message : No constructor could take the source type, or constructor
overload resolution was ambiguous
1>D:\pdgm\kits\trunk\boost\1.74.0\Win_x64_10_v16_debug\include\boost/mp11/detail/mp_with_index.hpp(371):
message : see reference to function template instantiation 'std::monostate
boost::mp11::detail::mp_with_index_impl_<3>::call<0,_Ty>(size_t,F &&)'
being compiled
1> with
1> [
1>
_Ty=avro::codec_traitspdgm::eml::etp12::Datatypes::IndexValue_item_v::decode::,
1>
F=avro::codec_traitspdgm::eml::etp12::Datatypes::IndexValue_item_v::decode::
1> ]
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70):
message : see reference to function template instantiation 'std::monostate
boost::mp11::mp_with_index<3,avro::codec_traits<T>::decode::>(size_t,F
&&)' being compiled
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v,
1>
F=avro::codec_traitspdgm::eml::etp12::Datatypes::IndexValue_item_v::decode::
1> ]
1>D:\pdgm\trunk\psc3\SharedComponents\src\lib\pdgm\eml\etp12\Messages.hpp(70):
message : while compiling class template member function 'void
avro::codec_traits<T>::decode(avro::Decoder
&,std::variantstd::monostate,int64_t,double &)'
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]
1>D:\pdgm\kits\trunk\Avrocpp\1.9.2-Boost-1.74.0\Win_x64_10_v16_debug\include\avro/Specific.hh(341):
message : see reference to function template instantiation 'void
avro::codec_traits<T>::decode(avro::Decoder
&,std::variantstd::monostate,int64_t,double &)' being compiled
1> with
1> [
1> T=pdgm::eml::etp12::Datatypes::IndexValue_item_v
1> ]