具有多个参数的绑定函数导致C2027 [英] Binding functions with multiple arguments results in C2027
问题描述
我使用ChaiScript 5.3.1,我试图绑定函数到我自己的类,特别是setPosition函数,可以采取Vector3或3个浮动。
类和它的相关方法声明如下:
类DLLExport Actor
{
public:
Actor(Level * level,const String& name,Actor * parent);
virtual〜Actor();
void setPosition(const Real& x,const Real& y,const Real& z);
void setPosition(const Vector3& position);
};
,我试着像这样绑定:
m-> add(user_type< Actor>(),Actor);
m-> add(fun< void(Actor :: *)(const Vector3&)>(& Actor :: setPosition),setPosition);
这将产生以下编译器输出(Windows,MSVC 2013):
2功能(550):错误C2027:使用未定义类型'std :: _ Get_function_impl< _Fty>'
2> with
2> [
2> _Fty = void(__thiscall Actor :: *)(const Vector3&)
2> ]
2> .. \..\ScriptingDemo\Binder.cpp(60):参见类模板实例化'std :: function< void(__thiscall Actor :: *)(const Vector3&)& b $ b 2功能(551):错误C2504:'type':基类未定义
2功能(554):错误C2027:使用未定义类型'std :: _ Get_function_impl <_Fty>'
2& with
2> [
2> _Fty = void(__thiscall Actor :: *)(const Vector3&)
2> ]
2功能(554):错误C2146:语法错误:缺少';'标识符'_Mybase'
2功能(554):错误C4430:缺少类型说明符注意:C ++不支持default-int
编译器错误。 Clang和GCC都接受此SSCCE ,Visual C ++不接受。
这四个重载函数 chaiscript :: fun
声明如下:
/ * 1 * / template< typename T>
Proxy_Function fun(T t);
/ * 2 * / template< typename T>
Proxy_Function fun(const std :: function< T>& f);
/ * 3 * / template< typename T,typename Q>
Proxy_Function fun(T t,const Q& q);
/ * 4 * / template< typename T,typename Q,typename R>
Proxy_Function fun(T t,const Q& q,const R& r);
根据语言规则,此表达式:
fun< void(Actor :: *)(const Vector3&)>(& Actor :: setPosition)
结果调用重载1或重载2,重载解析将决定哪个。
显式模板参数,这是重载解决方案必须使用:
/ * 1 * / Proxy_Function fun Actor :: *)(const Vector3&)t);
/ * 2 * / Proxy_Function fun(const std :: function< void(Actor :: *)(const Vector3&)>& f);
std :: function< void(Actor :: *)(const Vector3&)>
是一个未定义的类型,所以重载2是不可行的。 Visual C ++似乎认为这是一个错误,但它不应该。
使用您的解决方法:
fun((void(Actor :: *)(const Vector3&))& Actor :: setPosition)
您正在将类型重载的成员函数
& Actor :: setPosition
的指针转换为类型void Actor :: *)(const Vector3&)
并允许模板参数推导进入,Visual C ++满足。
将更好地避免C风格的转换:
fun(static_cast< void(Actor :: *)(const Vector3& )>(& Actor :: setPosition))
I'm using ChaiScript 5.3.1, and I'm trying to bind functions to my own class, specifically a setPosition function which can take either a Vector3 or 3 floats.
The class and it's relevant methods are declared like so:
class DLLExport Actor { public: Actor(Level* level, const String& name, Actor* parent); virtual ~Actor(); void setPosition(const Real& x, const Real& y, const Real& z); void setPosition(const Vector3& position); };
and I'm trying to bind them like this:
m->add(user_type<Actor>(), "Actor"); m->add(fun<void (Actor::*)(const Vector3&)>(&Actor::setPosition), "setPosition");
This results in the following compiler output (Windows, MSVC 2013):
2functional(550): error C2027: use of undefined type 'std::_Get_function_impl<_Fty>' 2> with 2> [ 2> _Fty=void (__thiscall Actor::* )(const Vector3 &) 2> ] 2> ..\..\ScriptingDemo\Binder.cpp(60) : see reference to class template instantiation 'std::function<void (__thiscall Actor::* )(const Vector3 &)>' being compiled 2functional(551): error C2504: 'type' : base class undefined 2functional(554): error C2027: use of undefined type 'std::_Get_function_impl<_Fty>' 2> with 2> [ 2> _Fty=void (__thiscall Actor::* )(const Vector3 &) 2> ] 2functional(554): error C2146: syntax error : missing ';' before identifier '_Mybase' 2functional(554): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
解决方案This is a compiler bug. Clang and GCC both accept this SSCCE, Visual C++ does not.
The four overloaded functions
chaiscript::fun
are declared as so:/*1*/ template <typename T> Proxy_Function fun (T t); /*2*/ template <typename T> Proxy_Function fun (const std::function< T > &f); /*3*/ template <typename T, typename Q> Proxy_Function fun (T t, const Q &q); /*4*/ template <typename T, typename Q, typename R> Proxy_Function fun (T t, const Q &q, const R &r);
According to the language rules, this expression:
fun<void (Actor::*)(const Vector3&)>(&Actor::setPosition)
Results in a call to either overload 1 or overload 2, overload resolution will determine which.
After substituting the explicit template argument, this is what overload resolution will have to work with:
/*1*/ Proxy_Function fun (void (Actor::*)(const Vector3&) t); /*2*/ Proxy_Function fun (const std::function< void (Actor::*)(const Vector3&) > &f);
std::function< void (Actor::*)(const Vector3&) >
is an undefined type, so overload 2 is not viable. Visual C++ seems to think that this constitutes an error, but it should not.With your workaround:
fun((void(Actor::*)(const Vector3&))&Actor::setPosition)
You are casting the pointer to overloaded member function
&Actor::setPosition
to the typevoid(Actor::*)(const Vector3&)
and allowing template argument deduction to step in, and Visual C++ is content with that.You would be even better off avoiding C-style casts:
fun(static_cast<void(Actor::*)(const Vector3&)>( &Actor::setPosition ))
这篇关于具有多个参数的绑定函数导致C2027的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!