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