Possible Operator Usage/Deduction Error when Using REGISTER_STRUCT macros #458
-
Describe the bug To Reproduce Expected behavior Real (buggy) behavior Additional context // Type Helpers for std::optional
#include "sdbus-c++/sdbus-c++.h"
#include <optional>
template<typename T>
struct sdbus::signature_of<std::optional<T>> : public sdbus::signature_of<sdbus::Variant>{};
template<typename T>
inline sdbus::Message& operator<<(sdbus::Message& os, const std::optional<T> maybeValue){
static_assert(!std::is_same_v<T, bool>);
if(maybeValue){
os << sdbus::Variant(maybeValue.value());
}
else {
os << sdbus::Variant(false);
}
return os;
}
template<typename T>
inline sdbus::Message& operator>>(sdbus::Message& is, std::optional<T>& maybeValue){
static_assert(!std::is_same_v<T, bool>);
sdbus::Variant tmp;
is >> tmp;
if(tmp.containsValueOfType<T>()){
maybeValue = tmp.get<T>();
} else {
maybeValue = std::nullopt;
}
return is;
}
// This is working fine
struct Foo {
int member;
};
struct Bar {
std::optional<Foo> foo;
};
SDBUSCPP_REGISTER_STRUCT(Foo, member);
SDBUSCPP_REGISTER_STRUCT(Bar, foo);
// When using a type for which operators are already provided by the lib itself,
// it seems the template providers up top are not used/found by the compiler.
struct Foobar {
std::optional<int> foobar;
};
SDBUSCPP_REGISTER_STRUCT(Foobar, foobar); I'm basically looking for some guidance on this issue. Not really sure if its a bug with the lib or if I'm using it just wrong. Let me know if I can provide more info on this. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Hi, it's not dependent on a basic type defined by the lib -- you'll get the same error when you move The serialization and deserialization functions shall be placed in the Let me know if that helped. |
Beta Was this translation helpful? Give feedback.
-
@fwilmsh Here is the likely explanation to your issue: To find the correct
So the solution to this is as I said before: place the Alternatively, you can also place them in the namespace of your custom type (but extending |
Beta Was this translation helpful? Give feedback.
-
@fwilmsh Can we close the discussion thread? |
Beta Was this translation helpful? Give feedback.
-
It seems to work @sangelovic. Thanks for the detailed explanation. |
Beta Was this translation helpful? Give feedback.
@fwilmsh Here is the likely explanation to your issue:
To find the correct
operator<<
implementation, the compiler involves unqualified name lookup (UNL) as well as argument dependent lookup (ADL) when building the set of candidates for overloaded operator resolution:In case of
Bar
registration, theSDBUSCPP_REGISTER_STRUCT
macro callssdbus::detail::serialize_pack()
method which callsoperator<<
for all struct members. So from the context ofsdbus::detail::serialize_pack()
, when resolvingoperator<<()
forstd::optional<Foo>
the compiler finds these candidates: