在C ++中高效传递字符串文字

时间:2012-06-07 14:21:24

标签: c++ string templates

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

我可以选择两个功能:

  1. void lua_pushstring (lua_State* L, const char* str);
  2. void lua_pushlstring(lua_State* L, const char* str, size_t len);
  3. 当然,第一个函数在内部使用strlen(),第二个函数因此更快。

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

    // 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中的较长函数中1}}文件:

    // 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,因此从不调用。

    有没有一种聪明的方法可以解决这个问题?

3 个答案:

答案 0 :(得分:3)

如果你声明两个,第二个转发到第一个:

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());

答案 1 :(得分:3)

我会提供两种选择:

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

(或者更确切地说是std::size_t),现在拥有字符串文字的用户可以调用第二个内部调度到第一个字符串。没有文字但const char*的用户有责任提供正确的尺寸。

答案 2 :(得分: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;
}

在此处查看测试运行:
错误的参数 - &gt;链接器错误:http://ideone.com/vZbj6
Rigt参数 - &gt;运行得很好:):http://ideone.com/iJBAo