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

complains using void as template argument

48 views
Skip to first unread message

anhongl...@gmail.com

unread,
Dec 31, 2018, 11:44:52 PM12/31/18
to


Hi Experts,

I am new to the c++ language and I tried the following code.
basically I have many different kind of requests and I would like to register a callback when the request get a response.
sometimes the request doesn't ask for a response with information, then the res_t should be void.

The following code complains I am using the void as template argument.
someone suggests me to define another exactly same function, but take std::function<void()> as argument.

I tried and succeeds. Is this the only way to get rid of this error?
Can I just have one function request() body to take care of all thes void /non-void cases?
Because for these two request() function I am just copying code.

Thanks,
Anhong



/////// code

struct req_1_t
{
using parms_t = struct
{
int id;
std::string buf;
};
using res_t = int;
};

struct req_2_t
{
using parms_t = struct
{
int id;
int value;
};
using res_t = void;
};

template<typename T> void request(typename T::parms_t /* parms_list */, std::function<void(typename T::res_t)> /* on_done */)
{}

// template<typename T> void request(typename T::parms_t parms_list, std::function<void()> on_done)
// {}

int main()
{
request<req_1_t>({}, [](int){});
request<req_2_t>({}, []( ){}); // error, complains using void as template argument

return 0;
}

Alf P. Steinbach

unread,
Jan 1, 2019, 12:40:39 AM1/1/19
to
The syntax like

int main( void )

is just a device used in C to indicate that a function does not have any
arguments. It doesn't mean that there is an argument of type `void`. And
it's a literal syntax, where the keyword `void` could just as well have
been `__gah__` or say `noargs` or whatever, so you can't, say, define
`using X = void;` and write `int main( X )`, just as you could not have
defined `using X = __gah__;`, because `__gah__` isn't a type here.

C++ supports the syntax for compatibility, but otherwise it's
meaningless in C++, a pure C-ism, because (unlike in C) in C++ `int
main()` states directly that the function has no arguments.

So, that's why the code doesn't compile: there is just no such thing as
an argument of type `void`. The C-ism syntax is just misleading. Though,
for convenience, one /can/ do `return void()` for a function returning
`void`, proving that ~nothing's free of special case rules in C++.

Technically you can save the current code by, for example, introducing a
traits template whose specializations map from `req_N_t::res_t` to some
function type used for your callback argument.

But I would work on the design instead of the coding.

Because it sounds a bit fishy to me to have callbacks with different
number of arguments. I'd work on unifying that.


Cheers!,

- Alf

Sam

unread,
Jan 1, 2019, 8:48:20 AM1/1/19
to
anhongl...@gmail.com writes:

> template<typename T> void request(typename T::parms_t /* parms_list */,
> std::function<void(typename T::res_t)> /* on_done */)
> {}

You have to use specialization to deal with this situation, with a helper
template, something along the lines of:

template<typename T> struct on_done_t {

typedef std::function<void (T)> type;
};

template<> struct on_done_t<void> {

typedef std::function<void ()> type;
};


template<typename T> void request(typename T::parms_t /* parms_list */,
typename on_done_t<typename T::res_t>::type);


Tim Rentsch

unread,
Mar 11, 2019, 2:01:13 PM3/11/19
to
"Alf P. Steinbach" <alf.p.stein...@gmail.com> writes:

> The syntax like
>
> int main( void )
>
> is just a device used in C to indicate that a function does not have
> any arguments. It doesn't mean that there is an argument of type
> void`. And it's a literal syntax, where the keyword `void` could just
> as well have been `__gah__` or say `noargs` or whatever, so you can't,
> say, define `using X = void;` and write `int main( X )`,

using X = void;

int
main( X ){
return 0;
}

Compiles fine here.

Alf P. Steinbach

unread,
Mar 11, 2019, 2:21:45 PM3/11/19
to
Interesting. Was I wrong that it's a literal syntax, or are both g++ and
Visual C++ wrong to accept the code?


Cheers!,

- Alf

Tim Rentsch

unread,
Mar 12, 2019, 8:48:39 AM3/12/19
to
I didn't look, I just tried compiling it. Looking now in n4659,
it looks like the relevant passage is in 11.3.5 p4 (the two "`"
characters added to indicate a code typeface):

A parameter list consisting of a single unnamed parameter of
non-dependent type `void` is equivalent to an empty parameter
list.

The type X is a not a dependent type (I had to look up dependent
types to know what that meant), so I think this form is blessed
by the standard.
0 new messages