Indiana Unversity logo[ConceptGCC]

ConceptGCC :

Re: Unable to write a concept map template with a requires clause specifying a type derived from a class template

From: Douglas Gregor (dgregor_at_[hidden])
Date: 2007-06-25 16:23:26


Tom Honermann wrote:
> I've been trying to use conceptgcc-BoostCon on Linux/x86 to write a
> concept map template to apply to types that derive from a base
> template class, but not having much luck...
>
> Consider this code:
>
> #include <concepts>
>
> concept C<typename T> {}
>
> template<typename T>
> struct Base {};
>
> // template concept map to apply to any type that is derived from
> Base<T>
> template<typename T, std::DerivedFrom<Base<T>> TDerived>
> concept_map C<TDerived> {}
>
> struct Derived : public Base<char> {};
>
> template<C T>
> void Foo(T t) {}
>
> int main() {
> Derived d;
> Foo(d);
> return 0;
> }
>
> Compiling this results in the following error:
>
> file.cpp:10: error: template parameters not used in partial
> specialization:
> file.cpp:10: error: `T'
> file.cpp: In function `int main()':
> file.cpp:19: no matching function for call to `Foo(Derived&)'
> file.cpp:15: note: candidates are: void Foo(T) [with T = Derived]
> <where clause>
> file.cpp:19: note: no concept map for requirement `C<Derived>'
> file.cpp:3: note: concept `C<Derived>' syntactically matches
> file.cpp:19: note: if the concept semantics are met, write a
> concept map:
> concept_map C<Derived> {};
>
> I have been unable to identify any section in n2193 that specifies
> that all template parameters must be referenced within the concept-id
> concept_map is mapping. It seems to me that use of all template
> parameters by a combination of the requires clause and concept-id
> should be supportable, so I'm not sure if this is an unimplemented
> feature in conceptgcc, a bug, a design/specification issue, or a
> misunderstanding on my part.
It appears that N2193 doesn't say this explicitly... the bug, here, is
in the specification. A concept map template behaves a lot like a class
template partial specialization, and one needs to be able to deduce all
of the template arguments from a use of the concept. Without this rule,
the compiler would need to essentially search for any 'T' that meets the
requirements stated on the concept map. This search would essentially be
unbounded (*any* possible C++ type might satisfy the requirements!) and
would probably return multiple results... causing ambiguities in even
the simplest cases. I see why this feature could be useful, but it just
can't be made to work without a lot of unfortunate caveats. Java
generics managed to get a very limited form of this working with its
"wildcards", but the same technique cannot work in the context of C++
because concepts are more general than Java generics.

The workarounds you gave are the best approaches that I know of.

  - Doug