On 2014-07-27 19:01, Andrew Sutton wrote:
In the 59638 case, the declarations
void (*a)(auto);
void (*b)(auto) = 0;
are shorthand for
template <typename T> void (*a)(T);
template <typename T> void (*b)(T) = 0;
which, unless there's some constraint with variable templates that
I'm not
aware of, ought to define two variable templates 'a' and 'b' to be
ptr-to-function-taking-T. So I think it's correct that the variable
template stuff should be triggering here.
There isn't, but this interpretation isn't consistent with the use of
auto in variable declarations.
True. It's just what GCC currently does when it see's 'auto' in a
function parameter list. Sounds like it needs to be prevented from
doing that in [at least] this case.
For example, this:
const auto& x = 0;
does not mean:
template<typename T> const T& x = 0;
So I would be surprised if any of:
void (*p1)(auto);
auto (*p2)(int);
vector<auto> x;
did mean "create a template" instead of "deduce the type of x".
Indeed. I accept the argument. The only reason GCC does this is that
it has a general implementation that introduces a template parameter
list to the primary declaration whenever it sees 'auto' in a function
parameter list; including a function parameter list in a function type.
If we know that we are not declaring a function (or know that we are
declaring a variable), then we can prevent 'auto' from having the
currently implemented meaning. That would be an alternative resolution
to 59638 (and friends) too.
Also, if we did have this interpretation of auto for some (but not
all?) variable declarations, we would have to know to write those as
template-ids:
void (*p)(auto);
p<int> = some_f;
since one cannot refer to a template specialization without
arguments.
Agreed. That's not pleasant. And I question whether there's a
motivating use case for variable templates that are function pointers
(but I confess I haven't thought much about it).
I'm much, much happier if, for variable templates, we always deduce
the type from the initializer.. Besides, that wording (or some
approximation thereof) is already in the TS for concepts. A question
came up during the CWG review as to whether we could declare function
parameters as void (*p)(auto), and EWG said, "sure, go for it". We
also have the ability to declare function parameters as, e.g.,
vector<auto> or pair<const auto&, auto*>. I applied that to variable
templates as well, since it would have been a bit inconsistent,
otherwise.
Sounds good. For function parameters this is implemented in GCC by
introducing a template declaration; i.e. making the function in question
a function template. For variables we want a different solution that
relies on doing some sort of tsubst of an initializer expression into
the 'auto'-expressed variable type; effectively generalizing the
handling of 'auto x = ...'. We could probably leverage the current
behavior to get the generalized ("generic") type including template
parameters, then do a substitution using the initializer expression to
determine what they are (and error if no initializer is given).
Adam