Date: Thu, 10 Sep 2020 09:19:37 -0400
On Thu, Sep 10, 2020 at 5:30 AM Fabio Alemagna via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I've been following the work on P1858
> <http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1858r2.html> and
> just yesterday it occurred to me that it'd be useful to do something like
> this:
>
> template <typename... Ts>
>
> struct Interface
>
> {
>
> rtype<Ts> func(ptype<Ts>) *...* = 0;
>
> };
>
>
> template <typename... Ts>
>
> struct Implementation: Interface<Ts...>
>
> {
>
> rtype<Ts> func(ptype<Ts> p) override
>
> {
>
> return impl<Ts>(p);
>
> } *...*
>
> };
>
>
> where rtype<>, ptype<> and impl<> are fictional templates with
> exposition-only purpose.
>
Interesting idea, but it puts the '...' much too inconspicuously for my
liking. The compiler would have to parse the entire function body before
it'd be able to diagnose a missing '...' in the signature!
template<class... Ts>
struct X {
void f(Ts ts) {
}
};
^ error: '}' where '...' was expected; did you forget a '...' before 'ts'
on line 3?
Besides, recursive templates aren't needed here. You could simulate what
you seem to want by just doing
template<class T>
struct Interface {
virtual rtype<T> func(ptype<T>) = 0;
};
template<class T>
struct ImplDetail : Interface<T> {
rtype<T> func(ptype<T> p) override { impl<T>(p); }
};
template<class... Ts>
struct Implementation : ImplDetail<Ts>... {};
This does involve one layer of indirection (the ImplDetail layer), but it's
not recursive (not even in the colloquial sense of "recursive templates")
and it's legal all the way back to C++11 IIRC.
As a possible usability bonus, this implementation makes it so that
`Implementation<Cat, Dog, Snake>` publicly derives from `Interface<Dog>`.
In your version, there is no `Interface<Dog>` class at all, and
`Interface<Cat, Dog, Snake>` is a *different type* from `Interface<Dog,
Snake, Cat>`.
HTH,
Arthur
std-proposals_at_[hidden]> wrote:
> I've been following the work on P1858
> <http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1858r2.html> and
> just yesterday it occurred to me that it'd be useful to do something like
> this:
>
> template <typename... Ts>
>
> struct Interface
>
> {
>
> rtype<Ts> func(ptype<Ts>) *...* = 0;
>
> };
>
>
> template <typename... Ts>
>
> struct Implementation: Interface<Ts...>
>
> {
>
> rtype<Ts> func(ptype<Ts> p) override
>
> {
>
> return impl<Ts>(p);
>
> } *...*
>
> };
>
>
> where rtype<>, ptype<> and impl<> are fictional templates with
> exposition-only purpose.
>
Interesting idea, but it puts the '...' much too inconspicuously for my
liking. The compiler would have to parse the entire function body before
it'd be able to diagnose a missing '...' in the signature!
template<class... Ts>
struct X {
void f(Ts ts) {
}
};
^ error: '}' where '...' was expected; did you forget a '...' before 'ts'
on line 3?
Besides, recursive templates aren't needed here. You could simulate what
you seem to want by just doing
template<class T>
struct Interface {
virtual rtype<T> func(ptype<T>) = 0;
};
template<class T>
struct ImplDetail : Interface<T> {
rtype<T> func(ptype<T> p) override { impl<T>(p); }
};
template<class... Ts>
struct Implementation : ImplDetail<Ts>... {};
This does involve one layer of indirection (the ImplDetail layer), but it's
not recursive (not even in the colloquial sense of "recursive templates")
and it's legal all the way back to C++11 IIRC.
As a possible usability bonus, this implementation makes it so that
`Implementation<Cat, Dog, Snake>` publicly derives from `Interface<Dog>`.
In your version, there is no `Interface<Dog>` class at all, and
`Interface<Cat, Dog, Snake>` is a *different type* from `Interface<Dog,
Snake, Cat>`.
HTH,
Arthur
Received on 2020-09-10 08:23:20