0

I'm trying to figure out the root cause of a type conversion issue with pointers to member functions in C++ (VS2012).

I've narrowed it down to the difference in the typeid of a pointer to a template member function and a non-template member function. Consider the code:

#include <typeinfo>
#include <iostream>

class foo
{
    public:    
        template<int k>
        void func1() {}

        void func2() {}
};

typedef void (foo::*foofunc)();

int main()
{
    //this gives "int"
    std::cout<<typeid(&foo::func1<3>).name()<<std::endl;

    //this gives "void (__thiscall *)(void)"
    std::cout<<typeid(&foo::func2).name()<<std::endl;

    return 0;
}

func2 has the expected value. Why does a pointer to func1 have type int when both are member functions of the same class?

NOTE: This happens only on Windows.

eerorika
  • 232,697
  • 12
  • 197
  • 326
Cygnus
  • 3,222
  • 9
  • 35
  • 65
  • On GCC 4.8, they both print `M3fooFvvE` – Paolo M Nov 19 '15 at 15:12
  • @PaoloM: Yeah. I'm not sure why the name is obscure but at least they both seem to have the same type with GCC. – Cygnus Nov 19 '15 at 15:15
  • What do you mean by obscure? By the way, this is from [cppreference](http://en.cppreference.com/w/cpp/language/typeid): There is no guarantee that the same std::type_info instance will be referred to by all evaluations of the typeid expression on the same type, although std::type_info::hash_code of those type_info objects would be identical, as would be their std::type_index. – Paolo M Nov 19 '15 at 15:22

1 Answers1

1

This clearly is a compiler bug in VS 2012. It looks closely related to #775434 "decltype is buggy in VS 2012" which links to this SO question. If this is indeed the bug, then you besides upgrading to VS 2015, you could try a workaround similar to this (src):

template <typename T> T msvc_decltype_helper(T); // Never implemented.
#define FN_DECLTYPE(...) decltype(::msvc_decltype_helper(__VA_ARGS__))

I.e. try what typeid(msvc_decltype_helper(&foo::func1<3>)).name() outputs.

Community
  • 1
  • 1
Oberon
  • 3,219
  • 15
  • 30