Indiana Unversity logo[ConceptGCC]

ConceptGCC :

Concept C++: excessive where-clauses?

From: Dietmar Kuehl (dietmar_kuehl_at_[hidden])
Date: 2007-01-21 19:41:14


Hi,

while working on a generic library (implementing the STL algorithms based
on property maps and cursors, of course), I started to use conceptgcc and
I came across a rather weird issue: concepts of internally used classes, i.e.
actually implementation details, need to be declared in the where-clauses
of checked templates. This is rather unexpected and causes, IMO, serious
usability problems. Thus, I want to make sure that this is merely an artifact
of the current implementation in GCC rather than the intended behavior.

Below is an example which demonstrates the point. Although it is somewhat
pointless by itself, the same issue arises when delegating e.g. from find()
to find_if(), using a corresponding function object: All what is required for
the function object to be instantiated is that the template arguments are
equality comparable. This is precisely the requirement imposed on them.
Thus, I would have expected that I can instantiate equal_to with the proper
types without further ado which, however, results in an error: the function
object can't be used with the function call operator until I explicitly add this
to the requirements! Why is this necessary? IMO I have already declared
everything which is necessary to call use this function object!

Thank you very much for any insights,
  Dietmar

-- 
<mailto:dietmar_kuehl_at_[hidden]> <http://www.dietmar-kuehl.de/>
--- CUT HERE ---
#include <concepts>
// -----------------------------------------------------------------------------
__concept equality_comparable<typename T1, typename T2>
{
  bool operator== (T1 const&, T2 const&);
};
__concept_map equality_comparable<int, int> {};
// -----------------------------------------------------------------------------
__concept predicate2<typename F, typename A0, typename A1>
{
  bool operator()(F&, A0, A1);
};
// -----------------------------------------------------------------------------
template <typename T1, typename T2 = T1>
__where equality_comparable<T1, T2>
struct equal_to
{
  bool operator()(T1 const& v1, T2 const& v2) const
  {
    return v1 == v2;
  }
};
template <typename T1, typename T2>
__where equality_comparable<T1, T2>
__concept_map predicate2<equal_to<T1, T2>, T1, T2>
{
};
// -----------------------------------------------------------------------------
template <typename T1, typename T2>
__where equality_comparable<T1, T2>
     && predicate2<equal_to<T1, T2>, T1, T2> // <----- is this necessary?
bool compare(T1 const& v1, T2 const& v2)
{
  equal_to<T1, T2> eq;
  return eq(v1, v2);
}
// -----------------------------------------------------------------------------
int main()
{
  return compare(17, 42);
}