Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Variadic Templates

21 views
Skip to first unread message

Alf P. Steinbach

unread,
Jul 13, 2019, 6:02:29 AM7/13/19
to
On 13.07.2019 11:30, Stefan Ram wrote:
> I have a PDF file with slides by Bjarne Stroustrup
> from 2011 or 2013 titled "C++11 The Future is here".
>
> I do not understand this slide (PDF page 40):
>
> |
> | Variadic templates
> |
> |o Any number of arguments of any types
> | template <class F, class ...Args> // thread constructor
> | explicit thread(F&& f, Args&&... args); // argument types must
> | // match the operation's
> | // argument types
> |
> | void f0(); // no arguments
> | void f1(int); // one int argument
> |
> | thread t1 {f0};
> | thread t2 {f0,1}; // error: too many arguments
> | thread t3 {f1}; // error: too few arguments
> | thread t4 {f1,1};
> | thread t5 {f1,1,2}; // error: too many arguments
> | thread t3 {f1,"I'm being silly"}; // error: wrong type of argument
> |
> | Stroustrup - TAMU - April 1
> |
>
> With "error: ", does he mean that this will be reported as
> an error?

Yes.


> How can the variadic template know that the args
> have to match the parameter list of f?

Because (but this is just my understanding from what you present here),
not shown above, it indirectly forwards the arguments to `f`.

I guess the reason Bjarne doesn't show that is because it's non-trivial,
involving the constructor creating a pack of arguments as a data member,
and then, asynchronously, the real thread function picking up those
arguments and forwarding them to `f`.

The real thread function part that forwards the arguments is necessarily
generated by the constructor, by instantiating some template.


> Or is this really an
> inbuilt feature of variadic templates I have not learned
> about yet? AFAIK the template does not even know that f is
> a function (prototype).

Right, that's an orange herring.


Cheers!,

- Alf

Sam

unread,
Jul 13, 2019, 11:19:29 AM7/13/19
to
Stefan Ram writes:

> | void f0(); // no arguments
> | void f1(int); // one int argument
> |
> | thread t1 {f0};
> | thread t2 {f0,1}; // error: too many arguments
> | thread t3 {f1}; // error: too few arguments
> | thread t4 {f1,1};
> | thread t5 {f1,1,2}; // error: too many arguments
> | thread t3 {f1,"I'm being silly"}; // error: wrong type of argument
> |
> | Stroustrup - TAMU - April 1
> |
>
> With "error: ", does he mean that this will be reported as
> an error? How can the variadic template know that the args
> have to match the parameter list of f?

The template does not care. The template will be expanded, as called, using
whatever parameters went into the parameter pack. At this point the number
of parameters to the function will not match, and a compilation error will
occur.

Alf P. Steinbach

unread,
Jul 13, 2019, 4:38:35 PM7/13/19
to
On 13.07.2019 18:15, Stefan Ram wrote:
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>> an error? How can the variadic template know that the args
>> have to match the parameter list of f? Or is this really an
>
> Thanks for the responses!
>
> I have observed that
>
> typedef decltype
> ( ::std::bind
> ( ::std::forward< F >( f ),
> ::std::forward< Args >( args )...)) _G;
>
> in the constructor body will detect a wrong number of
> arguments for "f" at a constructor call at compile time
> due to a static assertion
>
> static_assert(sizeof...(_BoundArgs) == sizeof...(_Args))
>
> in ::std::bind in <functional> here. But this will not catch a
> wrong type of an argument. But maybe there are implementations
> of ::std::bind around that will detect this too.

Apparently you're saying that with `std::bind` you can bind an incorrect
type of argument, and not have it checked if you don't try to call the
result functor. That makes sense. A class template can have member
functions that wouldn't compile if they were called.

template< class T >
struct S
{
void foo() { 1*T(); }
};

auto main() -> int
{
S<char*> o;
#ifdef FAIL
o.foo();
#else
(void) o;
#endif
}

If you want an up-front error:

I suggest you just put a call of it in a conditional where it's
guaranteed not executed.



Cheers!,

- Alf
0 new messages