具有多个参数的绑定函数导致C2027 [英] Binding functions with multiple arguments results in C2027

查看:375
本文介绍了具有多个参数的绑定函数导致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 type void(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆