0

我正在使用 ChaiScript 5.3.1,我正在尝试将函数绑定到我自己的类,特别是一个 setPosition 函数,它可以采用 Vector3 或 3 个浮点数。

该类及其相关方法的声明如下:

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

我正在尝试像这样绑定它们:

m->add(user_type<Actor>(), "Actor");
m->add(fun<void (Actor::*)(const Vector3&)>(&Actor::setPosition), "setPosition");

这会产生以下编译器输出(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
4

2 回答 2

2

这是一个编译器错误。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 (void (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 ))
于 2014-08-25T19:49:14.710 回答
0

不知道如何,确切地说,但我是这样修复的:

m->add(fun((void(Actor::*)(const Vector3&))&Actor::setPosition), "setPosition");

我很高兴我找到了答案,如果有人能解释为什么这样做会很好。

于 2014-08-25T18:02:33.743 回答