3

在编写包装 Lua 的代码时,我遇到了传递字符串文字的需求,并开始想知道哪种方式最有效。

我可以在两个功能之间进行选择:

  1. void lua_pushstring (lua_State* L, const char* str);
  2. void lua_pushlstring(lua_State* L, const char* str, size_t len);

当然,第一个函数在strlen()内部使用,因此第二个更快。

现在,如果它在编译时已知,我想避免计算字符串长度,如此此处所述:

// Overload 1
template <size_t N>
inline void pushstring(lua_State* L, const char (&str) [N])
{
    lua_pushlstring(L, str, N-1);
}

与使用字符串文字调用此函数一样好:pushstring(L, "test");当然,使用 a 调用时它不会编译const char*,例如在.cpp文件中较长的函数中:

// this is in a .cpp file
void long_function(lua_State* L, const char* str)
{
    // do lots of stuff
    pushstring(L, str);  // compile error
    // do more stuff
}

现在如果我添加

// Overload 2
inline void pushstring(lua_State* L, const char* str)
{
    lua_pushstring(L, str);
}

出于某种原因(C++ 重载解决方案很棘手),它优先于Overload 1,因此永远不会被调用。

有没有聪明的方法来解决这个问题?

4

3 回答 3

4

如果您同时声明第二个转发到第一个:

void lua_pushlstring(lua_State* L, const char* str, size_t len);

inline void lua_pushstring (lua_State* L, const char* str)
{ lua_pushlstring(L, str, strlen(str)); }

然后,当您使用文字调用第二个函数时,一个体面的编译器将优化strlen调用,例如它将内联

lua_pushstring(L, "hello");

并且因为strlen可以将文字优化为常量,所以它将用以下调用替换它:

lua_pushlstring(L, "hello", 5);

这为您提供了调用两个参数形式的简单语法,而无需支付strlen文字费用。

当长度已知时,可以通过:

lua_pushlstring(L, s.c_str(), s.length());

或者这也有效,但有不必要的调用strlen

lua_pushstring(L, s.c_str());
于 2012-06-07T14:31:28.307 回答
3

我会提供两种选择:

void f( const char*, int );
template <int N> void f( const char (&str)[N] ) {
   f( str, N-1 );
}

(或者更确切地说std::size_t),现在拥有字符串文字的用户可以调用第二个,该第二个将在内部分派给第一个。没有文字但有 a 的const char*用户负责提供正确的大小。

于 2012-06-07T14:33:12.470 回答
2

要进一步详细说明您的模板版本:

#include <iostream>

template <typename T>
inline void pushstring(T str);

template <int N>
inline void pushstring(const char (&str) [N])
{
   std::cout << N << std::endl;
}

template <>
inline void pushstring(const char *str)
{
   std::cout << str << std::endl;
}

在此处查看测试运行:
错误参数 -> 链接器错误:http
: //ideone.com/vZbj6 Rigt 参数 -> 运行良好 :): http: //ideone.com/iJBAo

于 2012-06-07T14:44:59.283 回答