如何区分char [3]和带有三个字符的字符串文字?

时间:2014-03-09 21:56:29

标签: templates c++11 generic-programming

如果我调用此函数:

template <typename t>
size_t
Foo(const T& str) {
  return std::distance(std::begin(str), std::end(str));
}

......有这三种类型:

const auto a = "abc";
const char b[3] = {'a', 'b', 'c'};
const std::string c("abc");

第一个类型将返回4(包括null),其他类型返回3.我如何区分这些类型以便它们都返回三个(字符数)?

1 个答案:

答案 0 :(得分:0)

字符串文字"abc"包含空终止符字节。 a的声明与

的声明相同
char a[] = { 'a', 'b', 'c', '\0' };

如果您不想计算终止或其后的字符,可以使用std::strlen。但是,这依赖于该字节的存在,并且在给定b时可能会崩溃。你可以设置一个重载:

template< typename t >
std::size_t string_length( t const & s ) {
    return s.size();
}

std::size_t string_length( char const * s ) { // requires a termination byte!
    return std::strlen( s );
}

template< std::size_t n > // requires the name of the array to be passed!
std::size_t string_length( char const (&s)[n] ) {
    return std::find( &* s, s + n, '\0' ) - s;
}

然而,这是一种非常危险的做法,因为如果将b数组分配给char *变量,该变量将选择第二个重载,但缺少终止符字节。