[ConceptGCC] |
ConceptGCC :Re: variadic templates and concepts |
From: Douglas Gregor (dgregor_at_[hidden])
Date: 2007-11-20 11:07:04
Hello Sylvain,
Sylvain Pion wrote:
> I am working on specifying an extension of std::min() to a variable
> number of arguments using variadic templates. For the concept-enabled
> version, I need to define a concept that constrains all arguments
> to be of the same type. That is, an extension of std::SameType to the
> variadic case.
>
> I am stuck with a problem using conceptgcc, which I fear is a bug,
> or maybe a misunderstanding on my side. A reduced test-case is below,
> which generates the following error message:
>
> bug_report.cpp: In function 'const T& f(const T&, const T&, const
> Args& ...)':
> bug_report.cpp:23: error: no matching function for call to 'f(const
> T&, #'type_pack_expansion' not supported by
> dump_type_prefix#<typeprefixerror>&#'type_pack_expansion' not
> supported by dump_type_suffix#)'
>
> ------------------------------
> concept SameType <typename T, typename... Args> {}
>
> template <typename T>
> concept_map SameType<T> {}
>
> template <typename T>
> concept_map SameType<T, T> {}
>
> template <typename T, typename... Args>
> requires SameType<T, Args...>
> concept_map SameType<T, T, Args...> {}
Hmmm. SameType is one of the built-in concepts, so its form is fixed by
the language to the two-type variant:
concept SameType<typename T, typename U> { }
Another version of SameType would either have no built-in meaning for
the compiler (if it's not in namespace std) or be ill-formed (if it is
in namespace std).
That said, we actually have two interesting options here. First of all,
we could write your SameType concept in terms of std::SameType:
auto concept SameType<typename T, typename... Rest> {
requires std::SameType<T, Rest>...;
}
That expands to requirements std::SameType<T, Rest1> && std::SameType<T,
Rest2> & ... & std::SameType<T, RestN>.
Or, of course, we could change the specification to make std::SameType
variadic.
> template <typename T, typename... Args>
> requires SameType<T, Args...>
> const T&
> f(const T&a, const T&b, const Args&... args)
> { return f(a, args...); }
Using std::SameType, one could write this as:
template <typename T, typename... Args>
requires std::SameType<T, Args>...
const T&
f(const T&a, const T&b, const Args&... args)
{ return f(a, args...); }
Unfortunately, ConceptGCC's support for variadic templates with concepts
is essentially non-existent, so you aren't going to be able to test this
with an actual implementation. Sorry!
- Doug