24

Can I legally use names for template parameters in std::function (or another similar construct)? E.g. given the code

std::function<int(int, int)> some_func;

Can I rewrite it in following way?

std::function<int(int begin, int end)> some_func;

It would be very nice, if it is standard compliant, because the type alone carries little information about the purpose of the parameter.

So far I've tested it in Visual Studio 2013 and it works. Edit: It works with gcc 4.8.1 too.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
ciechowoj
  • 914
  • 6
  • 26
  • 1
    Have you tried to do it? If works, well ... then you can. – Raydel Miranda Sep 08 '14 at 18:14
  • 14
    @RaydelMiranda: It would only prove that his compiler accepts it, not that the standard allows it. – celtschk Sep 08 '14 at 18:16
  • 4
    §8.3.5/11 [dcl.fct] "An identifier can optionally be provided as a parameter name;" `int (int, int)` is a function, so the clause applies here. – David G Sep 08 '14 at 18:24
  • 1
    `int (*foo)(int begin, int end) = nullptr` basically. – Yakk - Adam Nevraumont Sep 08 '14 at 18:25
  • @celtschk Yes, you're right, but that's not the question. He ask if he **can** and obviusly he did. If it is standar or not if a different question. – Raydel Miranda Sep 08 '14 at 18:44
  • 6
    @RaydelMiranda: Quotes from the question (emphasis by me): "Can I **legally** use […]", "[…] if it is **standard compliant,** […]" That makes it absolutely clear that the question is about what the standard allows. – celtschk Sep 08 '14 at 20:08

2 Answers2

22

Yes, you can provide the parameter name. From paragraph §8.3.5/11 of the C++11 Standard:

An identifier can optionally be provided as a parameter name;

The same goes for pointer-to-function and pointer-to-member function type. Personally, I would use the identifier only if it expresses more clearly the intention of your code.

David G
  • 94,763
  • 41
  • 167
  • 253
9

For the language lawyers:

The grammar does allow this. Whether or not this is intentional is unclear to me. A declarator and an abstract-declarator differ in that the latter doesn't allow a name at the top level.

declarator:

  • ptr-declarator
  • noptr-declarator parameters-and-qualifiers trailing-return-type

ptr-declarator:

  • noptr-declarator
  • ptr-operator ptr-declarator

noptr-declarator:

  • declarator-id attribute-specifier-seq (opt)
  • noptr-declarator parameters-and-qualifiers
  • noptr-declarator [ constant-expression (opt) ] attribute-specifier-seq (opt)
  • ( ptr-declarator )

Note that in a declarator you can have a declarator-id, that is, a name. Now consider the syntax of an abstract-declarator:

abstract-declarator:

  • ptr-abstract-declarator
  • noptr-abstract-declarator (opt) parameters-and-qualifiers trailing-return-type
  • abstract-pack-declarator

ptr-abstract-declarator:

  • noptr-abstract-declarator
  • ptr-operator ptr-abstract-declarator (opt)

noptr-abstract-declarator:

  • noptr-abstract-declarator (opt) parameters-and-qualifiers
  • noptr-abstract-declarator (opt) [ constant-expression (opt) ] attribute-specifier-seq (opt)
  • ( ptr-abstract-declarator )

An abstract-declarator can't contain a declarator-id at top level. However, notice that the parameters-and-qualifiers that occurs in the production rules for abstract-declarator and noptr-abstract-declarator is the same as that in declarator and noptr-declarator. There is no special abstract-parameters-and-qualifiers to enforce not having a name within a parameter list that occurs in an abstract-declarator. So the grammar allows names to be specified for function parameters inside abstract-declarators even though the overall function type can't be given a name.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312