在C++中高效传递字符串文本
Efficient passing of string literals in C++
在编写包装Lua的代码时,我遇到了传递字符串文字的需求,并开始想知道哪种方式最有效。
我可以在两个功能之间进行选择:
-
void lua_pushstring (lua_State* L, const char* str);
-
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");
当然,当用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
,因此永远不会被调用。
有没有聪明的方法来解决这个问题?
我会提供两个选项:
void f( const char*, int );
template <int N> void f( const char (&str)[N] ) {
f( str, N-1 );
}
(或者更确切地说是std::size_t
),现在具有字符串文本的用户可以调用将在内部调度到第一个的第二个。没有文字但有const char*
的用户负责提供正确的大小。
如果将第二个转发到第一个声明两者:
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());
要进一步详细说明您的模板版本:
#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
相关文章:
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 在编译时检查字符串文本的长度
- 读取字符串文本输入以创建 2D 矢量
- 管理字符串文本的最佳做法
- 定义宏以将前缀 0x 添加到十六进制字符串文本
- 无法在模板参数中定义字符串文本
- 不推荐使用 PTCHAR 的字符串文本
- C++ 字符串文本和常量
- C++20字符串文本模板参数工作示例
- 返回从字符串文本创建的静态string_view是否安全?
- 在处理任何字符大小的模板中使用字符串文本
- 是否保证相同内容字符串文本的存储相同?
- 将以 null 结尾的字节字符串转换为原始字符串文本
- 是否可以创建一个用户定义的文本,将字符串文本转换为 own 类型的数组?
- 使用C++中的模板检测不同的字符串文本
- 无法完全专用化字符串文本的模板
- C++ - 确定 const char* 是指向字符串文本对象还是动态对象
- 是否可以在原始字符串文本中插入转义序列?
- C++带有捕获组的正则表达式字符串文本
- 为什么多维数组中的空字符串文本衰减为空指针?