3

我的代码是用 mingw/g++ 编译器完美构建的,但 MSVC (2010) 遇到错误。问题是重载的函数和模板。可能有人知道 MSVC 的解决方法吗?如果不存在解决方法(证明链接不可用),它也会回答。

代码示例:

#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;
}

我的输出:

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

这是ideone构建结果。

4

1 回答 1

2

Foo::funcWithParammatch void (Class::*func)(ARG1)in的两个重载MemberFunction(Class * obj, void (Class::*func)(ARG1), ARG1 arg1),因此第二个参数类型不明确:编译器无法确定 ARG1 是int还是const char *

有趣的是,如果您在模板化构造函数中反转参数的顺序,即使其如下所示: MemberFunction(Class * obj, ARG1 arg1, void (Class::*func)(ARG1) )并将您的调用站点更改为: MemberFunction(&f, 5, &Foo::funcWithParam) 它将起作用。编译器首先遇到第二个参数,从中推断出类型 ARG1 is int。然后它继续到第三个参数,因为它现在知道 ARG1 是int,它知道要选择 &Foo::funcWithParam 的哪个重载。

我不确定在这种情况下标准规定的行为应该是什么,但其中一个编译器肯定有一个错误,很可能是 VS2010。

于 2012-09-21T08:56:47.647 回答