1

我正在围绕 Lua 的 C Api 编写一个简单的包装器,并让函数采用 lua_State& 而不是指针。但是,当我尝试传递 lua_State* 值时,我必须取消引用它才能通过引用传递。扩展为的模板具有 func sig ,其中 vm 按值传递,而不是引用。

由于可以在没有完整定义的情况下使用对象的引用和指针,有没有一种方法可以仅使用类型的前向声明将指针值转换为被引用的值?

编辑:在玩了更多代码之后。取消引用适用于其中一个函数调用,但在另一个函数调用上失败。

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

使用引用时不需要完整的定义,但是当您使用VMas实例化模板时,您也有一些按值传递的参数lua_State。并且值参数确实需要在调用站点和定义函数的位置进行完整声明。

在您的代码中,Vm::push专门用于lua_State&and double,因此您获得了专门化Vm::push( *luaState, (double)1.2f ); (但为什么(double)1.2f,而不仅仅是1.2?),因此您获得了专门化。Vm::pop但是, for lua_State&和没有专门int化,因此您获得了模板的实例化,该模板使用按值传递。(我假设这不是Uint32. 的 typedef 。)int

于 2013-09-23T18:32:51.483 回答
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

相关部分是 5.3.1 [expr.unary.op] 第 1 段:

一元 * 运算符执行间接:应用它的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是一个左值,指向表达式指向的对象或函数。如果表达式的类型是“指向 T 的指针”,则结果的类型是“T”。[ 注意:指向不完整类型(除了 cv void)的指针可以被取消引用。这样获得的左值可以以有限的方式使用(例如,初始化引用);此左值不得转换为纯右值,见 4.1。——尾注]

也就是说,您可以取消引用指向不完整类型的指针以获取对不完整类型的引用。您将无法使用由此获得的参考做很多事情。基本上,您将无法做任何需要定义不完整类型的事情。

于 2013-09-23T18:25:21.553 回答