I was playing with std::function
and encountered behavior that I don't understand. I was hoping someone could explain to me what's going on in the code at the bottom of the question.
Providing function type directly of course works. Simiralry with typedef.
The "fun" part begins when I use alias declaration (two commented out lines). Declaring type with using
results in compiler giving me an error:
[build] /home/lehu/workspaces/cpp-learning/std-func/main.cpp: In function ‘int main()’:
[build] /home/lehu/workspaces/cpp-learning/std-func/main.cpp:17:37: error: aggregate ‘std::function<int (&)()> func2’ has incomplete type and cannot be defined
[build] 17 | std::function<test_func_type_2> func2;
[build] | ^~~~~
[build] gmake[2]: *** [std-func/CMakeFiles/std-func.dir/build.make:82: std-func/CMakeFiles/std-func.dir/main.cpp.o] Błąd 1
I checked the types and typeid
shows that both test_func_type_1
and test_func_type_2
have the same type (following is output of the program):
1
FivE
FivE
If the types are the same, why one version works and other doesn't?!?
The code I was fiddling with:
#include <functional>
#include <iostream>
int test_func() {
return 10;
}
int main() {
std::function<int()> func; //providing function type directly is ok
func = test_func;
typedef int (test_func_type_1)();
std::function<test_func_type_1> func1; //typedef works as well
func1 = test_func;
using test_func_type_2 = int (&) (); //alias declaration is ok (can't use function pointer!)
//std::function<test_func_type_2> func2; <-- here we get compiler error
//func2 = test_func;
std::cout << (typeid(test_func_type_1) == typeid(test_func_type_2) ) << std::endl;
std::cout << typeid(test_func_type_1).name() << std::endl;
std::cout << typeid(test_func_type_2).name() << std::endl;
return 0;
}
EDITS
using test_func_type_2 = int (&) ();
into
using test_func_type_2 = int ();
results in error disappearing. However I would like to understand why my version is not compiling even if the types are aparently the same.
int (&) ()
and int ()
are not the same type. The former is reference to the latter. typeid
gives the same result because it ignores referenceness.
If the type of the type-id is a reference to a possibly cv-qualified type, the result of the
typeid
expression refers to astd::type_info
object representing the cv-unqualified referenced type.