0

私は ChaiScript 5.3.1 を使用しており、関数を独自のクラス、具体的には Vector3 または 3 つの float のいずれかを取ることができる setPosition 関数にバインドしようとしています。

クラスとそれに関連するメソッドは次のように宣言されます。

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++ は受け入れません。

オーバーロードされた 4 つの関数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 に答える