address of c++ template function

后端 未结 3 1632
一生所求
一生所求 2021-01-07 18:41

Why does this fail to compile? (g++-4.5)

template < typename U >
static void h () {
}

int main () {
  auto p = &h; // error: p has inco         


        
相关标签:
3条回答
  • 2021-01-07 18:48

    Try

     auto p  = static_cast<void(*)()>(& h<int>);
    

    Because gcc treats templated function as overloaded one. From the gcc's point of view it's like you would have h(int param) and h(float param) - which one the compiler has to choose?

    I noticed what was the problem in older versions of gcc, but I'll try to explain it more verbosely. GCC couldn't deduce the type, because templated function was treated like overloaded one. It was basically like you would have the following:

    void h(int)
    {
    }
    
    void h(float)
    {
    }
    
    void (*p)(int) = & h;  //ok
    void (*p)(float) = & h; //ok
    auto p = & h; //error: which version of h?
    

    For gcc h<int> was just like overloaded h function with endless alternatives depending onT parameter. With the code provided in question it was O.K. to do the following:

    void (*p)() = & h<int>;
    

    (that's why I don't get typedefed "work-around")

    As I thought OP wanted to use c++11 auto keyword as suggested by a tag, I statically casted h<int> to void(*)(), which is kind of no-operation, just to trick gcc, because it was not able to deal with templated functions and auto correctly.

    Functions void h<int>() and void h<float>() should be of course treated like different functions with the same pointer type and not overload versions of h function. When instantiated they should behave like void hInt() and void hFloat() and you should be able to use auto like here:

    void hInt()
    {
    }
    
    void hFloat()
    {
    }
    
    auto p = hInt;
    p = hFloat;
    

    But for some reason for gcc they were like overloaded versions of h.

    Please give a reason for downvotes.

    0 讨论(0)
  • 2021-01-07 18:57

    It does not compile because type of 'p' is not known to the compiler which is a must in C++ unlike some other languages.

    Try

    template < typename U > 
    static void h () { 
    } 
    
    int main () { 
      auto void (*p)() = &h<int>; 
    } 
    
    0 讨论(0)
  • 2021-01-07 19:00

    In C++0x this is guaranteed to work. However in C++03 this wasn't working (the initializer part, that is) and some compilers apparently don't support it yet.

    Furthermore, I remember that the C++0x wording is not clear what happens with &h<int> when it is an argument to a function template and the corresponding parameter is deduced (this is what auto is translated to, conceptionally). The intention is, however, that it is valid. See this defect report where they designed the wording, the example by "Nico Josuttis" and their final example.

    There is another rule that the wording enforces but compilers are not correctly implementing. For example, see this clang PR.

    0 讨论(0)
提交回复
热议问题