3

Lua をラップするコードを書いているときに、文字列リテラルを渡す必要があることに気づき、どの方法が最も効率的か疑問に思い始めました。

次の 2 つの機能から選択できます。

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

もちろん、最初の関数はstrlen()内部的に使用するため、2 番目の関数の方が高速です。

ここで、コンパイル時にわかっている場合は、ここここに示されているように、文字列の長さの計算を避けたいと思います。

// 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");呼び出された場合、コンパイルされません。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

2番目のものを最初のものに転送して両方を宣言する場合:

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次に、リテラルを使用して2番目の関数を呼び出すと、適切なコンパイラが呼び出しを最適化します。たとえば、インラインになります。

lua_pushstring(L, "hello");

リテラルは定数に最適化できるためstrlen、次の呼び出しに置き換えられます。

lua_pushlstring(L, "hello", 5);

strlenこれにより、リテラルにお金を払うことなく、2つの引数の形式を呼び出す簡単な構文が得られます。

長さがすでにわかっている場合は、次のように渡すことができます。

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

または、これも機能しますが、strlen

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

私は2つのオプションを提供します:

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

(というかstd::size_t)、文字列リテラルを持つユーザーは、内部的に最初のリテラルにディスパッチする 2 番目を呼び出すことができます。リテラルではなく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 に答える