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

Reply via email to