0

I have this code

int f(int i){
        return i;
}
int main(){
    cout << std::boolalpha;
    using f_1 = decltype(f);
    using f_2 = decltype((f));
    cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
    cout << is_same<std::result_of_t<f_2(int)>, int>::value<< endl; // OK
    return 0;
}

If I am correct, decltype(f) will return the type of the function which will be int(int). decltype((f)) will return the type of reference of the function which will be int(&)(int). In the documentation of result_of, it said: F must be a callable type, reference to function, or reference to callable type. Invoking F with ArgTypes... must be a well-formed expression. So is that mean a function type is not an callable type?

Error info is

1.23.cpp: In function ‘int main()’:
1.23.cpp:35:38: error: ‘type name’ declared as function returning a function
   35 |     cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
      |                                      ^~~
1.23.cpp:35:46: error: template argument 1 is invalid
   35 |     cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
      |                                              ^
1.23.cpp:35:52: error: template argument 1 is invalid
   35 |     cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR
      |                                                    ^
Kevin eyeson
  • 375
  • 4
  • 8
  • Did you read [notes](https://en.cppreference.com/w/cpp/types/result_of#Notes) on cppreference? Also note that `result_of` was removed from the language, we have `invoke_result` now instead. – HolyBlackCat Jan 24 '23 at 05:47
  • @HolyBlackCat Yes I read notes. Because my future work will only working on C++11/14 so I have to use some old stuffs. – Kevin eyeson Jan 24 '23 at 05:49
  • 1
    The notes explain this quirk. `f_1(int)` is a function type, with `f_1` being its return type. You can't return functions by value, hence `f_1` being a function type doesn't work. But you can return them by reference. – HolyBlackCat Jan 24 '23 at 05:51
  • Thank you for the explanation. I think I misunderstand the note. So the basic reason why the first one is an error and the second one is OK is that function can't return a function, but the function can return a reference/pointer to the function? @HolyBlackCat – Kevin eyeson Jan 24 '23 at 06:02
  • 1
    You probably want `result_of_t`. – n. m. could be an AI Jan 24 '23 at 06:17
  • 1
    I usually use `std::is_same_v` since that also works when f_1 has overloads, or when f_1 would return a lambda – Pepijn Kramer Jan 24 '23 at 06:19

1 Answers1

3

A function cannot have a function type as return type. It can have a reference-to-function return type though.

So already in terms of the simple meaning of the syntax f1(int), the program is ill-formed. It would denote the type of a function that takes an int and returns a function type (f1).

The behavior of std::result_of using an invented function type as template argument is a bit weird and causes these issues. That's one of the reasons it has been replaced with std::invoke_result which takes the callable and argument types as individual template arguments, so that no function type needs to be invented.

user17732522
  • 53,019
  • 2
  • 56
  • 105