Why is the cPP function pointer not a function after dereferencing?

define a function and a pointer to it, and then determine whether the function pointer is a function after dereferencing

void test1() {}
int main()
{
    void(*t1)() = test1;
    std::cout << std::is_function<decltype(*t1)>::value << std::endl;
    std::cout << std::is_function<decltype(test1)>::value << std::endl;
    std::cout << (typeid(decltype(test1)).hash_code() == typeid(decltype(*t1)).hash_code()) << std::endl;
    
    return 0;
}

the final output is:

0
1
1

directly compare the types of * T1 and test1, and the results show that the types are the same, but why the first output is 0
I know that when a function is called with a function name, it will be converted to a function pointer
. Do you wonder why the wrong
is caused by the rules of template matching parameters? Partial implementation of is_function:

template<typename>
    struct is_function
    : public false_type { };

  template<typename _Res, typename... _ArgTypes>
    struct is_function<_Res(_ArgTypes...)>
    : public true_type { };
CPP
Apr.29,2021

because the pointer is not a function, the so-called function, when compiling, will write the corresponding symbol table, and the pointer loses all the information of the function, just an entry address. If std::is_function determines that the pointer is a function, then it can be considered that whether a bug, is semantically or logically correct.


The result of

decltype (* T1) is not a function, but a function reference, because * T1 returns a lvalue, that returns a reference type for lvalue,decltype.
that is, not

void()

but

void (&) ()

is_function cannot take effect naturally because it is a reference. Use remove_reference to remove this reference.

-sharpinclude <iostream>
-sharpinclude <type_traits>
-sharpinclude <typeinfo>
void test1() {}
typedef void TEST();

int main()
{
        TEST* t1 = test1;
        std::cout << std::is_reference<decltype(*t1)>::value << std::endl; //1
        std::cout << std::is_function<std::remove_reference<decltype(*t1)>::type>::value << std::endl; // 1
                        
        return 0;
}
Menu