gpt4 book ai didi

c++ - std::end 以 char 的原始数组结尾

转载 作者:太空狗 更新时间:2023-10-29 20:42:24 24 4
gpt4 key购买 nike

默认情况下,原始数组的 std::end 重载看起来像这样:

template<class T, std::size_t N>
T* end(T (&array)[N])
{ return array + N; }

但是,在传递字符串文字或 char 数组时,我不希望这种重载,因为它们在末尾都有一个隐式的 \0 被计算在内。

我想作为一种解决方法,我可以在我自己的命名空间中重载 end:

示例:

namespace unique
{
const char* end(const char (&array)[5])
{
return array + 4;
}
const char* end(const char (&array)[11])
{
return array + 10;
}
}

int main()
{
using std::begin;
using std::end;
using unique::end;
const char str1[] = "XXXTEXTXXX";
const char str2[] = "TEXT";
auto iter = std::search(begin(str1), end(str1), begin(str2), end(str2));
//...
}

但是,这将需要大量的重载来编写。

问题

我意识到使用 std::string 或其他容器可以解决我的问题。但是,我希望能够使用字符串文字或原始数组调用不合格的 end 并让它像上面那样省略空终止符。有没有更好的方法可以避免编写重载?

最佳答案

显而易见的(如果您确定它只会在正确的情况下使用)将是原始版本的变体:

namespace unique {
template<class T, std::size_t N>
T* end(T (&array)[N])
{ return array + N-1; }
}

只要确保只在正确的情况下使用它,否则你将得到 end,它在结束前指向一个。

如果你想将它限制为字符类型,你可以使用几个只对字符类型有效的重载:

namespace unique {
template <std::size_t N>
char *end(char (&array)[N])
{
return array + N - 1;
}

template <std::size_t N>
wchar_t *end(wchar_t (&array)[N])
{
return array + N - 1;
}
}

这样,char 数组将使用假定 NUL 终止符的版本,但 int 数组将使用 std::end 所以它指的是整个数组:

int main()
{
using std::begin;
using std::end;
using unique::end;
char str1 [] = "12345";
wchar_t str2 [] = L"12345";
int i4 [] = { 1, 2, 3, 4, 5, 6 };

std::cout << std::distance(begin(str1), end(str1)) << "\n";
std::cout << std::distance(begin(str2), end(str2)) << "\n";
std::cout << std::distance(begin(i4), end(i4)) << "\n";
}

但是请注意,由于存在一个名为 begin 的模板,这些重载只会匹配确切的类型,因此如果您希望它们与 const char 一起使用,并且const wchar_t(例如)那些将需要与上面使用非常量类型的那些分开的重载。

另请注意,这些仍适用于 typedef,因此(例如)相当常见的:

typedef char small_int;

...可能/将导致问题——实际类型仍然是 char,因此 end(my_small_int_array) 将使用 char 重载而不是基本模板.

关于c++ - std::end 以 char 的原始数组结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18732352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com