C++ 是编译时“;strlen();有效?

C++ 是编译时“;strlen();有效?,c++,string,templates,performance,C++,String,Templates,Performance,有时有必要将字符串的长度与常量进行比较。 例如: if ( line.length() > 2 ) { // Do something... } 但我试图避免在代码中使用“神奇”常量。 通常我使用这样的代码: if ( line.length() > strlen("[]") ) { // Do something... } 它可读性更强,但由于函数调用的缘故,效率不高。 我编写了如下模板函数: template<size_t N> size_t _l

有时有必要将字符串的长度与常量进行比较。
例如:

if ( line.length() > 2 )
{
    // Do something...
}
但我试图避免在代码中使用“神奇”常量。
通常我使用这样的代码:

if ( line.length() > strlen("[]") )
{
    // Do something...
}
它可读性更强,但由于函数调用的缘故,效率不高。
我编写了如下模板函数:

template<size_t N>
size_t _lenof(const char (&)[N])
{
    return N - 1;
}

template<size_t N>
size_t _lenof(const wchar_t (&)[N])
{
    return N - 1;
}

// Using:
if ( line.length() > _lenof("[]") )
{
    // Do something...
}
好的是编译器在二进制输出中不包含“[]”字符串


这是特定于编译器的优化还是常见的行为?

内联函数调用的功能既是特定于编译器的优化,也是常见的行为。也就是说,许多编译器都可以做到这一点,但它们不是必需的。

为什么不呢

sizeof "[]" - 1; 大小为“[]”-1; (尾部空值减去1。您可以 执行sizeof“[]”-sizeof'\0',但执行sizeof'\0' 在C中通常是sizeof(int),而“-1”是 完全可读。)


说真的,为什么要经历这些麻烦来避免输入2?老实说,我认为你正在降低代码的可读性,而其他程序员会盯着你看,就像你在从过滤器中吸食用过的咖啡一样。

我认为大多数编译器在启用优化后都会对其进行优化。如果它们被禁用,可能会使您的程序速度大大降低

我更喜欢您的模板函数,因为它们保证不会在运行时调用
strlen
。 当然,与为
char
wchar\u t
编写单独的函数不同,您可以添加另一个模板参数,并获得适用于任何类型的函数:

template <typename Char_t, int len>
int static_strlen(const Char_t (&)[N] array){
  return len / sizeof(Char_t) - 1;
}
模板
int静态字符串(常量字符(&)[N]数组){
返回len/sizeof(Char\u t)-1;
}
(正如评论中已经提到的,如果传递一个int数组,这将给出有趣的结果,但是您可能会这样做吗?毕竟这是针对字符串的)

最后一点,名字
\u strlen
不好。命名空间范围中以下划线开头的所有名称都保留给实现。你可能会遇到一些令人讨厌的命名冲突

顺便问一下,为什么“[]”的魔法常数小于2


在这两种情况下,如果与之比较的字符串格式发生变化,则必须更改该文本。

这只是一个示例。在实际代码中,它看起来像“某个字符串”。在这种情况下,是否要计算字符数?:)是的,我是。我会的。我知道。@Jed-Smith::)如果字符串发生变化,您确定不会忘记更改宏定义吗?@Jed-Smith:“2”比sizeof([])更可读/更容易理解吗?@Jed:嘿,如果它只是一个2,为什么还要麻烦呢?当它是“一些字符串,我可能会改变,我不想打扰眼睛的长度”,这是一个不同的故事。哦,strlen()只是一个真正的问题。假设这是一个问题,这是一种猜测形式。对于宽字符串,可以修复此问题。类似于:
(sizeof(L“[]”)/sizeof(L“)-1
@Evan Teran:是的,但您应该使用宏使其更具可读性。IMHO宏它更像C风格,但不是C++我同意,只是指出这种技术适用于宽字符串。我不赞成:-P.您可能可以对所有数组类型使用一个模板,但有一点是这样的:
模板大小\u t_lenof(const t(&)[N]){return N-1;}
,应该仍然与您的示例相同。@Evan Teran:好主意,但这些函数仅对字符串(char/wchar________t数组)有意义,因为终止“\0”。您的函数将用于int[10]并返回9-我认为这没有意义;)@埃文·特兰:N==0?怎么用?偶数N==1。函数返回0-这是正确的。我不确定你的标题问题是什么意思。你是说编译时间吗?你说的“有效”是什么意思?我认为gcc的机器很有可能会解决这个问题。我的意思是,如果它关心消除
sin(1)
,那么对于
strlen(“foo”)
:)所需的优化并不(仅仅)需要内联。它要求在编译时计算字符串的长度,但这并不是真正的优化。在运行时不会计算长度,并且仍然调用任何
\u lenof
函数。标准不要求实现为字符串文本提供类型
const char[N]
?编译器推断模板函数的参数为
N
,难道不需要这种类型的值吗?对不起,我误解了你的答案所指的内容-出于某种原因,我认为你说的是“由于[strlen]函数调用而没有效率”。如果编译器不能内联的列夫,那么它可能不能内联任何东西,并且一般来说是一个非常糟糕的C++编译器。任何严重使用模板的行为都是噩梦……无论出于何种原因,您的函数似乎并不比使用strlen快。但是,它似乎比使用std::char\u traits::length要快,所以它仍然很有用,因为strlen只在char数组上工作。
#define TWO 2
#define STRING_LENGTH 2
/* ... etc ... */
template <typename Char_t, int len>
int static_strlen(const Char_t (&)[N] array){
  return len / sizeof(Char_t) - 1;
}