diff --git a/gtsam/base/GenericValue.h b/gtsam/base/GenericValue.h index f7b5e985a..4fe5bc143 100644 --- a/gtsam/base/GenericValue.h +++ b/gtsam/base/GenericValue.h @@ -187,4 +187,11 @@ private: struct PoolTag { }; }; +// define Value::cast here since now GenericValue has been declared +template + const ValueType& Value::cast() const { + return dynamic_cast&>(*this).value(); + } + + } /* namespace gtsam */ diff --git a/gtsam/base/Value.h b/gtsam/base/Value.h index 4d7104ad7..4ba468a87 100644 --- a/gtsam/base/Value.h +++ b/gtsam/base/Value.h @@ -122,6 +122,10 @@ namespace gtsam { /** Assignment operator */ virtual Value& operator=(const Value& rhs) = 0; + /** Cast to known ValueType */ + template + const ValueType& cast() const; + /** Virutal destructor */ virtual ~Value() {} diff --git a/gtsam/nonlinear/tests/testValues.cpp b/gtsam/nonlinear/tests/testValues.cpp index 5d82891dc..5fbe4d6af 100644 --- a/gtsam/nonlinear/tests/testValues.cpp +++ b/gtsam/nonlinear/tests/testValues.cpp @@ -353,12 +353,12 @@ TEST(Values, filter) { BOOST_FOREACH(const Values::Filtered<>::KeyValuePair& key_value, filtered) { if(i == 0) { LONGS_EQUAL(2, (long)key_value.key); - EXPECT(typeid(GenericValue) == typeid(key_value.value)); - EXPECT(assert_equal(pose2, dynamic_cast&>(key_value.value).value())); + try {key_value.value.cast();} catch (const std::bad_cast& e) { FAIL("can't cast Value to Pose2");} + EXPECT(assert_equal(pose2, key_value.value.cast())); } else if(i == 1) { LONGS_EQUAL(3, (long)key_value.key); - EXPECT(typeid(GenericValue) == typeid(key_value.value)); - EXPECT(assert_equal(pose3, dynamic_cast&>(key_value.value).value())); + try {key_value.value.cast();} catch (const std::bad_cast& e) { FAIL("can't cast Value to Pose3");} + EXPECT(assert_equal(pose3, key_value.value.cast())); } else { EXPECT(false); } @@ -416,10 +416,10 @@ TEST(Values, Symbol_filter) { BOOST_FOREACH(const Values::Filtered::KeyValuePair& key_value, values.filter(Symbol::ChrTest('y'))) { if(i == 0) { LONGS_EQUAL(Symbol('y', 1), (long)key_value.key); - EXPECT(assert_equal(pose1, dynamic_cast&>(key_value.value).value())); + EXPECT(assert_equal(pose1, key_value.value.cast())); } else if(i == 1) { LONGS_EQUAL(Symbol('y', 3), (long)key_value.key); - EXPECT(assert_equal(pose3, dynamic_cast&>(key_value.value).value())); + EXPECT(assert_equal(pose3, key_value.value.cast())); } else { EXPECT(false); }