3

I was reading about std::function in part 3 this (long) answer on callbacks in C++ https://stackoverflow.com/a/28689902/3832877 and it demonstrates the use template arguments which have additional types in parentheses. Examples of what I mean:

std::function<int(int, float)> foo; //for a function returning int with one int and one float argument
std::function<int(C const &, int)> moo; //from the above thread, for member function of class C taking one int argument and returning int

I understand the usage in std::function to define the function signature, but I don't understand how the compiler is parsing these template arguments. What do the types in the parentheses mean to the compiler? Are there any other uses for this syntax or was it created specifically for std::function and related STL classes? Can I write my own classes that use this syntax?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Verwirrt
  • 403
  • 2
  • 13

1 Answers1

3

Those are types of functions. int(int,int) is the type of a function that takes two int parameters and returns an int.

For demonstration, consider this example:

#include <type_traits>
#include <iostream>

int foo(int,int){ return 42;}

int main(){
    std::cout << std::is_same< decltype(foo), int(int,int)>::value;
}

It compares the type of foo with the type int(int,int), and indeed the output is 1.

See also here: https://en.cppreference.com/w/cpp/language/function

The type of the function being declared is composed from the return type (provided by the decl-specifier-seq of the declaration syntax) and the function declarator

noptr-declarator ( parameter-list ) cv(optional) ref(optional) except(optional) attr(optional)    (1)     
noptr-declarator ( parameter-list ) cv(optional) ref(optional) except(optional) attr(optional) -> trailing    (2)     (since C++11)

Can I write my own classes that use this syntax?

Yes you can. In a nutshell, int(int,int) is just a type like others:

#include <iostream>

template <typename T>
void foo(T t){
    t(42);
}

void bar(int x) { std::cout << x; }

int main() {
   foo< void(int) >(bar);
   // ... or ...
   using fun_type = void(int);
   foo< fun_type >(bar);
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • That doesn't really explain the syntax involved, because if you declare a pointer to a function then you have to use `returntype(*ptr)(arguments)` so how is the compiler parsing this syntax as described by the OP? – Devolus Apr 19 '21 at 09:42
  • @Devolus I didnt understand the question as asking for details of parsing. OP is asking "What do the types in the parentheses mean to the compiler?" and "Are there any other uses for this syntax or was it created specifically for std::function and related STL classes?" I think my answer adresses both – 463035818_is_not_an_ai Apr 19 '21 at 09:43
  • @Devolus maybe my last edit is what you were missing. – 463035818_is_not_an_ai Apr 19 '21 at 09:44
  • The OP said `I understand the usage... but I don't understand how the compiler is parsing these template arguments.`. So is the syntax `int(int,int)` some special feature, because how does the template parser know that this means a function as there is no name involved. Because of the brackets? The examples in the link all are standard function definition, with the name of the function existing. – Devolus Apr 19 '21 at 09:45
  • AFAIK the important part of the question is, if this syntax can be used by other templates as well and how, or if it is some special thing for `std::function` and this is not addressed by the answer. – Devolus Apr 19 '21 at 09:52
  • 1
    @Devolus its a type like any other, I though that answers whether it is specific to `std::function` I also have an example without `std::function`. Anyhow, I'll add another – 463035818_is_not_an_ai Apr 19 '21 at 09:53
  • 1
    Ah! So `int(int, int)` is just "another" arbitrary type (even if it looks strange). That was not clear to me. Maybe you should change `foo with int(int,int)` to `foo with type int(int,int)` which would make it clearer IMO. – Devolus Apr 19 '21 at 09:56
  • Yes, that answers my question. The last example is and realisation that it is just another type like any other is what I was missing. Thanks! – Verwirrt Apr 19 '21 at 10:04