Boost logo

Boost :

Subject: Re: [boost] [function_types] Number of default parameters
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-12 12:11:30

On Tue, Feb 8, 2011 at 9:28 PM, Stephan T. Lavavej
<stl_at_[hidden]> wrote:
> [Lorenzo Caminiti]
>> I'm confused because the following code doesn't compile on MSVC but it
>> _does_ compiles fine on GCC...
>> typedef void (func_type)(double num = -1.23); // NO STANDARD??
>> 1) Is this a bug in GCC which should not accept `= -1.23` in `func_type`?
> VC is correct to reject this code. (So does EDG.)
> C++03 8.3.6 "Default arguments" [dcl.fct.default]/3: "A default argument expression shall be specified only in the parameter-declaration-clause of a function declaration or in a template-parameter (14.1). If it is specified in a parameter-declaration-clause, it shall not occur within a declarator or abstract-declarator of a parameter-declaration.88)"
> Footnote 88: "This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, or typedef declarations."
>> 2) Both, GCC and MSVC accept the parameter name `num` as part of the
>> `func_type` type. Can parameter names be specified in function types?
> Yes, that's totally fine, they're just ignored. C++03 8.3.5 "Functions" [dcl.fct]/8: "An identifier can optionally be provided as a parameter name", which applies to typedefs too.

Wow! Thanks a lot for all the standard references -- that's very
accurate information!

Also, are the function parameter storage classifiers `auto` and
`register` part of the function type? Can I manipulate (check, add,
and remove) them at compile-time using template metafunctions?

The expression `typedef int (f_type)(auto int x, register bool y);`
complies on both GCC and MSVC so maybe they are part of the function

NOTE: This is more of a curiosity because for my application I can
manipulate the storage classifiers using preprocessor metaprogramming.
In fact, `auto` and `register` are known alphanumeric tokens (i.e.,
keywords) that always appear at the beginning of the parameter type
expression so the following macros can be used to manipulate them:

#include <boost/preprocessor.hpp>
#include <boost/preprocessor/detail/is_unary.hpp>

#define IS_AUTO_auto (1) /* must expand to unary */
#define IS_AUTO(tokens) BOOST_PP_IS_UNARY(BOOST_PP_CAT(IS_AUTO_, tokens))

#define REMOVE_AUTO_STRIP_auto /* must expand to nothing */
#define REMOVE_AUTO(tokens) \
    BOOST_PP_IIF(IS_AUTO(tokens), \
        REMOVE_AUTO_ \
    , \
        tokens BOOST_PP_TUPLE_EAT(1) \

#define ADD_AUTO(tokens) \
    BOOST_PP_EXPR_IIF(BOOST_PP_NOT(IS_AUTO(tokens)), auto) tokens

IS_AUTO(auto int x) // 1
IS_AUTO(int x) // 0

REMOVE_AUTO(auto int x) // int x
REMOVE_AUTO(int x) // int x

ADD_AUTO(auto int x) // auto int x
ADD_AUTO(int x) // auto int x

(These macros work as long as the type expression starts with an
alphanumeric token -- if not, I can wrap the type expression using
Boost.Local's `BOOST_IDENTITY_TYPE` as in
`BOOST_IDENITY_TYPE(::std::string) s`.)


Boost list run by bdawes at, gregod at, cpdaniel at, john at