#7378 closed Bugs (fixed)
lookup_one_property fails if property tag not found
Reported by: | Owned by: | Douglas Gregor | |
---|---|---|---|
Milestone: | To Be Determined | Component: | graph |
Version: | Boost 1.52.0 | Severity: | Problem |
Keywords: | lookup_one_property property_value | Cc: |
Description
boost::lookup_one_property<PropertyList,Tag>::found
does not compile if Tag
is not found in the PropertyList
.
The problem originates from the lookup(...)
function definition in the template specialization
template <typename Tag, typename T, typename Base, typename PropName> struct lookup_one_property_internal<boost::property<Tag, T, Base>, PropName>: lookup_one_property_internal<Base, PropName> { private: typedef lookup_one_property_internal<Base, PropName> base_type; public: template <typename PL> static typename enable_if<is_same<PL, boost::property<Tag, T, Base> >, typename base_type::type&>::type lookup(PL& prop, const PropName& tag)
which requires the base class to provide a type
member.
If the tag is not found the unspecialized template
template <typename PList, typename PropName, typename Enable = void> struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false);};
will be instantiated as Base where the compiler can't find any type
member.
Attachments (2)
Change History (14)
by , 10 years ago
Attachment: | example.cpp added |
---|
follow-up: 2 comment:1 by , 10 years ago
Component: | property_map → graph |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
That change was made on purpose; it greatly helps error messages for using nonexistent property maps from graphs.
comment:2 by , 10 years ago
Replying to jewillco:
That change was made on purpose; it greatly helps error messages for using nonexistent property maps from graphs.
Is there another way of checking the existence of some particular property tag then?
comment:3 by , 10 years ago
Look at lookup_one_property<...>::found
. That takes a property list and a tag and determines if the property is present in the list. That doesn't give an easy way to test a graph for a given property, though.
comment:4 by , 10 years ago
That's what I thought, but lookup_one_property<...>::found
is not false
if the tag is not found, instead it just results in a compiler error.
comment:7 by , 10 years ago
The problem is that in the enable_if of the lookup(...) member function
template <typename Tag, typename T, typename Base, typename PropName> struct lookup_one_property_internal<boost::property<Tag, T, Base>, PropName>: lookup_one_property_internal<Base, PropName> { private: typedef lookup_one_property_internal<Base, PropName> base_type; public: template <typename PL> static typename enable_if<is_same<PL, boost::property<Tag, T, Base> >, typename base_type::type&>::type lookup(PL& prop, const PropName& tag)
typename base_type::type& does not depend on the template parameter of the template member function but only on the template parameters of the class. Therefore base_type::type is required to exist, even if lookup(...) is not used (or the enable_if<...> disables the function).
A solution could be to add a indirection which depeneds on PL
, like
template <class First, class Second> struct second_type { typedef Second type; }; ... static typename enable_if<is_same<PL, boost::property<Tag, T, Base> >, typename second_type<PL,base_type>::type::type&>::type lookup(PL& prop, const PropName& tag)
which will prevent the compiler from resolving base_type::type unless lookup(...) is explicitly instantiated.
This way the general template lookup_one_property_internal
does not need to define a type
member to use lookup_one_property<...>::found
.
But I have to admit that this solution looks a little ugly.
comment:8 by , 10 years ago
comment:9 by , 10 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
This was also my first approach, but unfortunately it doesn't solve the problem.
Since the return type of lookup(...)
is type&
the compiler will complain if type
is void
, as you can see if you try to compile my example code.
comment:10 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:11 by , 10 years ago
Great! That solved the problem. I totally forgot about lazy_enable_if...
Could you also apply the same fix to struct lookup_one_property<const T, Tag>
in line 159 of the same file?
Thanks for fixing the problem so quickly! :)
demonstration code