std::string と char[]型の end の位置

std::string と char[] 型で std::end() の返ってくる位置がずれている事に気がついた。
次のコードを実行させるとで実行時エラーが出る。

template<typename T>
int
distance(const T& range){
	return std::end(range) - std::begin(range);
}

char	array[] = "01234";
std::string str = "01234";

// distance(array) は、6 が返ってくるのに対し、
// distance(str) は、5 が返ってくる
assert( distance(array) == distance(str) );


これは、std::end(std::string) が終端NULLの位置を返しているのに対し、std::end(char[]) の場合は、終端NULLの次の位置を返しているのが原因である。
pstade::oven::distance も内部で begin と end の位置で比較を行っているので次の様なコードは非常にまずい。

assert( oven::distance("01234") == oven::distance(std::string("01234")) );

std::string str = static_cast<const std::string&>
		("HONEY TEE PARTY!"|oven::filtered(lambda::_1 != 'E')|oven::copied);

// str の中身は、"HONY T PARTY! "になっている…
assert( str == "HONY T PARTY!" );


文字列は全て std::string で扱ってしまったほうがよさそうだ。
他にも std::end() で比較している場所は全て怪しいな。


[※追記]
pstade::oven::as_literal を使えば解決するらしいです。

char	array[] = "01234";
std::string str = "01234";

assert( oven::distance(oven::as_literal("01234")) == oven::distance(str) );

str = static_cast<const std::string&>
		(oven::as_literal("HONEY TEE PARTY!")
			|oven::filtered(lambda::_1 != 'E')
			|oven::copied);
assert( str == "HONY T PARTY!" );


pstade::oven::as_literal は、文字配列(char[]型)を range に変換して返してくれます。
コメントありがとうございました。


[pstade]
ver 1.04.3