Просмотр исходного кода

Fixed error "ambiguous overload for operator|" (fixes #1411)

Benoit Blanchon 5 лет назад
Родитель
Сommit
2664a2d0da

+ 5 - 0
CHANGELOG.md

@@ -1,6 +1,11 @@
 ArduinoJson: change log
 =======================
 
+HEAD
+----
+
+* Fixed error `ambiguous overload for 'operator|'` (issue #1411)
+
 v6.17.0 (2020-10-19)
 -------
 

+ 1 - 0
extras/tests/MemberProxy/CMakeLists.txt

@@ -7,6 +7,7 @@ add_executable(MemberProxyTests
 	clear.cpp
 	compare.cpp
 	containsKey.cpp
+	or.cpp
 	remove.cpp
 	set.cpp
 	size.cpp

+ 29 - 0
extras/tests/MemberProxy/or.cpp

@@ -0,0 +1,29 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2020
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+using namespace ARDUINOJSON_NAMESPACE;
+
+TEST_CASE("MemberProxy::operator|()") {
+  DynamicJsonDocument doc(4096);
+
+  SECTION("const char*") {
+    doc["a"] = "hello";
+
+    REQUIRE((doc["a"] | "world") == std::string("hello"));
+    REQUIRE((doc["b"] | "world") == std::string("world"));
+  }
+
+  SECTION("Issue #1411") {
+    doc["sensor"] = "gps";
+
+    const char *test = "test";  // <- the literal must be captured in a variable
+                                // to trigger the bug
+    const char *sensor = doc["sensor"] | test;  // "gps"
+
+    REQUIRE(sensor == std::string("gps"));
+  }
+}

+ 1 - 10
src/ArduinoJson/Variant/VariantOperators.hpp

@@ -20,22 +20,13 @@ struct VariantOperators {
   // Returns the default value if the VariantRef is undefined of incompatible
   template <typename T>
   friend typename enable_if<!IsVisitable<T>::value, T>::type operator|(
-      const TVariant &variant, const T &defaultValue) {
+      const TVariant &variant, T defaultValue) {
     if (variant.template is<T>())
       return variant.template as<T>();
     else
       return defaultValue;
   }
 
-  // Returns the default value if the VariantRef is undefined of incompatible
-  // Special case for string: null is treated as undefined
-  template <typename T>
-  friend typename enable_if<is_same<T, const char *>::value, T>::type operator|(
-      const TVariant &variant, T defaultValue) {
-    const char *value = variant.template as<const char *>();
-    return value ? value : defaultValue;
-  }
-
   // value == TVariant
   template <typename T>
   friend bool operator==(T *lhs, TVariant rhs) {