fix: make Variant conversion operator explicit (#428)

Having explicit conversion operator is a good practice according to the C++ core guidelines, as it makes the code safer and better follows the principle of least astonishment. Also, it is consistent with the standard library style, where wrappers like std::variant, std::any, std::optional... also do not provide an implicit conversion to the underlying type. Last but not least, it paves the way for the upcoming std::variant <-> sdbus::Variant implicit conversions without surprising behavior in some edge cases.
This commit is contained in:
Stanislav Angelovič
2024-04-03 20:40:28 +02:00
parent 42f0bd07c0
commit 32a97f214f
5 changed files with 9 additions and 8 deletions

View File

@@ -1765,6 +1765,7 @@ sdbus-c++ v2 is a major release that comes with a number of breaking API/ABI/beh
* `PollData::getRelativeTimeout()` return type was changed to `std::chrono::microseconds`. * `PollData::getRelativeTimeout()` return type was changed to `std::chrono::microseconds`.
* `IConnection::processPendingRequest()` was renamed to `IConnection::processPendingEvent()`. * `IConnection::processPendingRequest()` was renamed to `IConnection::processPendingEvent()`.
* `Variant` constructor is now explicit. * `Variant` constructor is now explicit.
* `Variant`'s conversion operator to the underlying type is now explicit.
* `IProxy::getCurrentlyProcessedMessage()` now returns `Message` by value instead of a raw pointer to it. The caller assumes ownership of the message. * `IProxy::getCurrentlyProcessedMessage()` now returns `Message` by value instead of a raw pointer to it. The caller assumes ownership of the message.
* Object D-Bus API registration is now done through `IObject::addVTable()` method. The vtable gets active immediately. No `finishRegistration()` call is needed anymore. vtables can be added and removed dynamically at run time. In addition to API simplification this brings consistency with sd-bus API and increases flexibility. * Object D-Bus API registration is now done through `IObject::addVTable()` method. The vtable gets active immediately. No `finishRegistration()` call is needed anymore. vtables can be added and removed dynamically at run time. In addition to API simplification this brings consistency with sd-bus API and increases flexibility.
* Subscription to signals has been simplified. The subscription is active right after the `registerSignalHandler`/`uponSignal()` call. No need for the final call to `finishRegistration()`. * Subscription to signals has been simplified. The subscription is active right after the `registerSignalHandler`/`uponSignal()` call. No need for the final call to `finishRegistration()`.

View File

@@ -47,7 +47,7 @@ public:
public: public:
std::string Name() std::string Name()
{ {
return proxy_->getProperty("Name").onInterface(INTERFACE_NAME); return proxy_->getProperty("Name").onInterface(INTERFACE_NAME).get<std::string>();
} }
private: private:

View File

@@ -87,7 +87,7 @@ namespace sdbus {
// Only allow conversion operator for true D-Bus type representations in C++ // Only allow conversion operator for true D-Bus type representations in C++
template <typename _ValueType, typename = std::enable_if_t<signature_of<_ValueType>::is_valid>> template <typename _ValueType, typename = std::enable_if_t<signature_of<_ValueType>::is_valid>>
operator _ValueType() const explicit operator _ValueType() const
{ {
return get<_ValueType>(); return get<_ValueType>();
} }

View File

@@ -107,9 +107,9 @@ TYPED_TEST(SdbusTestObject, CallsMethodWithStructVariantsAndGetMapSuccesfully)
std::vector<int32_t> x{-2, 0, 2}; std::vector<int32_t> x{-2, 0, 2};
sdbus::Struct<sdbus::Variant, sdbus::Variant> y{false, true}; sdbus::Struct<sdbus::Variant, sdbus::Variant> y{false, true};
std::map<int32_t, sdbus::Variant> mapOfVariants = this->m_proxy->getMapOfVariants(x, y); std::map<int32_t, sdbus::Variant> mapOfVariants = this->m_proxy->getMapOfVariants(x, y);
decltype(mapOfVariants) res{ {sdbus::Variant{-2}, sdbus::Variant{false}} decltype(mapOfVariants) res{ {-2, sdbus::Variant{false}}
, {sdbus::Variant{0}, sdbus::Variant{false}} , {0, sdbus::Variant{false}}
, {sdbus::Variant{2}, sdbus::Variant{true}}}; , {2, sdbus::Variant{true}}};
ASSERT_THAT(mapOfVariants[-2].get<bool>(), Eq(res[-2].get<bool>())); ASSERT_THAT(mapOfVariants[-2].get<bool>(), Eq(res[-2].get<bool>()));
ASSERT_THAT(mapOfVariants[0].get<bool>(), Eq(res[0].get<bool>())); ASSERT_THAT(mapOfVariants[0].get<bool>(), Eq(res[0].get<bool>()));

View File

@@ -198,7 +198,7 @@ public:
public: public:
uint32_t action() uint32_t action()
{ {
return proxy_->getProperty("action").onInterface(INTERFACE_NAME); return proxy_->getProperty("action").onInterface(INTERFACE_NAME).get<uint32_t>();
} }
void action(const uint32_t& value) void action(const uint32_t& value)
@@ -208,7 +208,7 @@ public:
bool blocking() bool blocking()
{ {
return proxy_->getProperty("blocking").onInterface(INTERFACE_NAME); return proxy_->getProperty("blocking").onInterface(INTERFACE_NAME).get<bool>();
} }
void blocking(const bool& value) void blocking(const bool& value)
@@ -218,7 +218,7 @@ public:
std::string state() std::string state()
{ {
return proxy_->getProperty("state").onInterface(INTERFACE_NAME); return proxy_->getProperty("state").onInterface(INTERFACE_NAME).get<std::string>();
} }
private: private: