1

Lua の C API の周りに単純なラッパーを作成し、ポインターの代わりに lua_State& を関数に取り込ませています。ただし、 lua_State* 値を渡そうとすると、参照渡しするために逆参照する必要があります。展開されたテンプレートには、参照ではなく値で渡される vm を持つ func sig があります。

完全な定義なしでオブジェクトの参照とポインターを使用することは可能であるため、型の前方宣言だけでポインター値から参照される値に変換する方法はありますか?

編集:コードをもう少しいじった後。逆参照は、関数呼び出しの 1 つで機能しますが、別の関数では失敗します。

namespace Vm {

template<typename VM, typename T>
void push( VM vm, T value );

// If this function isn't here, push will fail too.
template<typename T>
void push( lua_State& luaState, T value ) {
    Vm::push( luaState, value );
}

template<>
void push( lua_State& luaState, double value ) {
    lua_pushnumber( &luaState, value );
}

template<typename VM>
void pop( VM vm, Uint32 nIndices );

template<>
void pop( lua_State& luaState, Uint32 nIndices ) {
    lua_pop( &luaState, nIndices );
}

}


int main( int argc, char** argv )
{
    lua_State* luaState = luaL_newstate();
    luaL_openlibs( luaState );
    Vm::push( *luaState, (double)1.2f ); // This works fine.
    Vm::pop( *luaState, 1 ); // This generates error.
}

コンパイラ エラー:

error: invalid use of incomplete type ‘struct lua_State’
error: forward declaration of ‘struct lua_State’
error:   initializing argument 1 of ‘void Vm::pop(VM, Uint32) [with VM = lua_State; Uint32 = unsigned int]’
4

3 に答える 3

1

Vm::pop の定義を変更して、VM パラメータに参照属性を持たせると、問題が解決するようです。

namespace Vm {    
template<typename VM>
    void pop( VM& vm, Uint32 nIndices );
}

筋金入りの関数型プログラマでない限り、毎回 VM のコピーを作成しても意味がありません。呼び出しが lua_State& ではなく lua_State に解決され、Vm::push ラッパー関数で適切に推定された理由はまだわかりません (これはなんとかしてより多くの情報を提供することができました..)。うーん、今はうまく機能しています。

手伝ってくれてありがとう!

于 2013-09-23T23:53:32.913 に答える
1

VM参照を使用する場合は完全な定義は必要ありませんが、テンプレートをasでインスタンス化する場合は、値渡しの引数もいくつか必要ですlua_State。また、値パラメーターは、呼び出しサイトと関数が定義されている場所で完全に宣言する必要があります。

あなたのコードでVm::pushは、 は と に特化されlua_State&doubleいるので、 の特化が得られますVm::push( *luaState, (double)1.2f ); (なぜ?(double)1.2fだけでなく1.2?) ため、特化が得られます。Vm::popただし、 for lua_State&およびは特殊化されていないintため、値渡しを使用するテンプレートのインスタンス化を取得します。(これはの typedefでUint32ないと思いますint。)

于 2013-09-23T18:32:51.483 に答える
1

関連するセクションは 5.3.1 [expr.unary.op] パラグラフ 1 です。

単項 * 演算子は間接参照を実行します。それが適用される式は、オブジェクト型へのポインター、または関数型へのポインターであり、結果は、式が指すオブジェクトまたは関数を参照する左辺値になります。式の型が「T へのポインタ」の場合、結果の型は「T」になります。[ 注: 不完全型 (cv void 以外) へのポインタは逆参照できます。このようにして得られた左辺値は、限られた方法で使用できます (たとえば、参照を初期化するため)。この左辺値は、prvalue に変換してはなりません。4.1 を参照してください。—終わりのメモ]

つまり、不完全な型へのポインターを逆参照して、不完全な型への参照を取得できます。このようにして得られた参照では、多くのことはできません。基本的に、不完全な型の定義を必要とすることは何もできません。

于 2013-09-23T18:25:21.553 に答える