Question

When I try to compile this code, I get the following compiler error in Visual Studio 2012:

error C2440: 'default argument' : cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'

My code:

namespace bar {
    template<typename T> void foo();
    template<> void foo<int>() {}
}

struct A {
    void(*f)();

    template<typename T> inline void set_func(void(*f)()=bar::foo<T>) {this->f=f;}
};

int main(void) {
    A a;
    a.set_func<int>();
    return 0;
}

When I move bar::foo into the global namespace, I don't get the error anymore. Can anyone please explain?

I've edited the above code to remove some confusion about member functions and template specialization. I also removed the typedef, which gives an even weirder version of the same error : cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'

Was it helpful?

Solution 2

Because this is quite obviously a bug in the compiler itself, all I can do is create a workaround to achieve the same effect.

I removed the default arguments and used an overloaded method as follows:

template<typename T> inline void set_func() {this->f=bar::foo<T>;}
template<typename T> inline void set_func(void(*f)()) {this->f=f;}

OTHER TIPS

Another work around for this problem.

typedef void (*FunctionPointer)(int, int);

class Template
{
    public:
        template<typename Type>
        static void Function(int Arg0, int Arg1)
        {
            // Code and Stuff
        }

        // ORIGINAL FUNCTION - Produces compile errors.
        // Produces - error C2440: 'default argument' : cannot convert from 'overloaded-function' to 'FunctionPointer' (VS2012 SP5 x64)
        template<typename Type>    
        void Original(FunctionPointer Arg = &Template::Function<Type>)
        {
            // Code and Stuff
        }

        // WORKAROUND FUNCTION - Compiles fine.
        // Default Arg parameter to NULL and initialize default parameter inside function on runtime.
        template<typename Type>    
        void Original(FunctionPointer Arg = NULL)
        {
            if (Arg == NULL)
                Arg = &Template::Function<Type>;

            // Code and Stuff
        }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top