简体   繁体   English

VS2010的解决方法:模板和重载函数

[英]Workaround for VS2010: templates and overloaded functions

I've code that are perfect build with mingw/g++ compilers but MSVC (2010) encountered error. 我的代码是使用mingw / g ++编译器完美构建的,但是MSVC(2010)遇到了错误。 Problem is overloaded functions and templates. 问题是重载的函数和模板。 May be somebody know workaround for MSVC? 可能有人知道MSVC的解决方法吗? If workaround not exist (proof link is diserable) it also answer. 如果没有解决方法(证明链接可以解决),它也​​会回答。

Code example: 代码示例:

#include <iostream>

struct Function 
{
    virtual ~Function() {}
    virtual void operator()() = 0;
};

template <typename Class, typename ARG1>
struct MemberFunction1 : public Function
{
    typedef void (Class::*MEM_FUNC)(ARG1);
    explicit MemberFunction1(Class * obj, MEM_FUNC func, ARG1 arg1) :  m_object(obj), m_func(func), m_arg1(arg1) {}

    virtual void operator()()
    {
        (m_object->*m_func)(m_arg1);
    }

    Class *  m_object;
    MEM_FUNC m_func;    
    ARG1     m_arg1;
};

struct FunctionStorage
{
    explicit FunctionStorage(Function * func) : m_func(func) {}

    virtual ~FunctionStorage()
    {
        if (m_func)
        {
            delete m_func;
            m_func = 0;
        }
    }

    void call() { (*m_func)(); }
    Function * m_func;
};

struct MemberFunction : public FunctionStorage
{
    template <typename Class, typename ARG1>
    MemberFunction(Class * obj, void (Class::*func)(ARG1), ARG1 arg1) : FunctionStorage(new MemberFunction1<Class, ARG1>(obj, func, arg1)) {}
};


class Foo 
{
public:
    void funcWithParam(int value)
    {
        std::cout << "foo::funcWithParam(" << value << ")\n";
    }
    void funcWithParam(const char * msg)
    {
        std::cout << "foo::funcWithParam(" << msg << ")\n";
    }
};

int main()
{
    Foo f;    
    MemberFunction(&f, &Foo::funcWithParam, 5).call(); // problem here, if remove one of funcWithParam (stay only 1 function, no overload) all will be ok
    MemberFunction(&f, &Foo::funcWithParam, "hello").call(); 
    return 0;
}

My output: 我的输出:

main.cpp(65): error C2660: 'MemberFunction::MemberFunction' : function does not take 3 arguments
main.cpp(65): error C2228: left of '.call' must have class/struct/union
main.cpp(66): error C2660: 'MemberFunction::MemberFunction' : function does not take 3 arguments
main.cpp(66): error C2228: left of '.call' must have class/struct/union

Here is ideone build result. 这是构思结果。

Both overloads of Foo::funcWithParam match void (Class::*func)(ARG1) in MemberFunction(Class * obj, void (Class::*func)(ARG1), ARG1 arg1) , so the second parameter type is ambiguous: the compiler can't decide whether ARG1 is int or const char * . Foo::funcWithParam两个重载Foo::funcWithParam匹配Foo::funcWithParam中的void (Class::*func)(ARG1) MemberFunction(Class * obj, void (Class::*func)(ARG1), ARG1 arg1) ,因此第二个参数类型是不明确的:编译器无法确定ARG1是int还是const char *

Funny thing is if you invert the order of parameters in your templated constructor, ie make it like this: MemberFunction(Class * obj, ARG1 arg1, void (Class::*func)(ARG1) ) and also change your call site to this: MemberFunction(&f, 5, &Foo::funcWithParam) it will work. 有趣的是,如果你在模板化构造函数中反转参数的顺序,即使它像这样: MemberFunction(Class * obj, ARG1 arg1, void (Class::*func)(ARG1) )并且还将您的调用站点更改为此: MemberFunction(&f, 5, &Foo::funcWithParam)它可以工作。 The compiler first encounters the second parameter from which it deduces the type ARG1 is int . 编译器首先遇到第二个参数,从中推导出类型ARG1为int It then proceeds to the third parameter and because it now knows ARG1 is int , it knows which overload of &Foo::funcWithParam to select. 然后它进入第三个参数,因为它现在知道ARG1是int ,它知道选择&Foo :: funcWithParam的哪个重载。

I am not sure what the behavior the standard dictates should be in this case, but one of the compilers surely has a bug, most likely VS2010. 在这种情况下,我不确定标准规定的行为应该是什么,但其中一个编译器肯定有一个bug,很可能是VS2010。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM