[英]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.