#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