Aug 19, 2018

[C++17] casting derived type member function to base type signature

https://ibob.github.io/blog/2018/08/18/a-bug-in-the-cpp-standard/

Interestingly if simply using:
template<auto MemFunc>
void run(Derived& d){
 (d.*MemFunc)();
}

would not have any issue, and that's exactly first thing pop up in my head.
However, just because the author tried other approach could this limitation being revealed :-)

tl;dl;
Below in main, code won't work:

iamproxy<static_cast<void (Base::*)()>(&Derived::brun)>(d);

explained why:
https://groups.google.com/a/isocpp.org/forum/embed/?place=forum/std-discussion#!topic/std-discussion/__QDbLgpFik

quoted:
The code is valid, but the Itanium C++ ABI does not specify a mangling for it yet, so compilers targeting that ABI tend to not accept it yet.
Clang produces a "sorry, not supported yet" error if you try this with a class template, but unfortunately you only get a generic "bad template arguments" error in the function template case.
#include <iostream>

using namespace std;


struct Base {
    void brun()
    {
        cout << "brun" << endl;
    }
};

struct Derived : Base {
    void drun()
    {
        cout << "drun" << endl;
    }
};


template <void (Base::*PTR)()>
void iamproxy(Derived &de)
{
    cout << "in test" << endl;
    (de.*PTR)();
}


int main()
{
    Derived d;
    iamproxy<static_cast<void (Base::*)()>(&Derived::brun)>(d);
}

In templates, there's no implicit type casting.
The non-type, type, template template should be exactly type match.
This is unlike runtime implicit casting,
i.e passing derived member function, either virtual / non-virtual non-static member function to functions taking pointer to based member function.

Above casting error message happens on virtual member function as well, due to same name mangling issue,
i.e, it can't even instantiate the template function.

Additional reference:
https://vsdmars.blogspot.com/2014/05/c-function-overload-resolution-is.html

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.