[range] strange behavior of operator== with iterator_range

Can someone tell me if the behavior demonstrated in the following program is intentional or a bug in Boost.Range? -- Bryce Lelbach aka wash boost-spirit.com px.cct.lsu.edu github.com/lll-project

On 05/18/2011 02:25 PM, Bryce Lelbach wrote:
Can someone tell me if the behavior demonstrated in the following program is intentional or a bug in Boost.Range?
It seems to be the expected behaviour. "foo" is the range {'f', 'o', 'o', '\0'} If you want {'f', 'o', 'o'}, use boost::as_literal("foo").

On Wed, May 18, 2011 at 9:25 PM, Bryce Lelbach <blelbach@cct.lsu.edu> wrote: Can someone tell me if the behavior demonstrated in the following program is intentional or a bug in Boost.Range? The short answer - intended! The long answer. Literal strings are not supported directly as ranges excepted when adapted by using the as_literal function. The supported types are listed here: http://www.boost.org/doc/libs/1_46_1/libs/range/doc/html/range/reference/ove... The literal string you are testing against is an array of chars of length 4. This array is including the null-terminator. The length of std::string does not include a null-terminator. The following is your code with my comments added. #include <iostream> #include <string> #include <boost/range/iterator_range.hpp> typedef boost::iterator_range<char const*> range_type; int main (void) { char const* foo = "foo"; { range_type r(foo, foo + 3); std::cout << r << std::endl; // <NeilGroves> // std::string("foo") has length 3 and content is equal, hence the // correct branch is taken. // </NeilGroves> if (r == std::string("foo")) std::cout << "success\n"; // branch taken else std::cout << "failure\n"; // <NeilGroves> // "foo" has type char[4] and therefore has length 4. Since the lengths // are not equal they are not equal. // </NeilGroves> if (r == "foo") std::cout << "success\n"; else std::cout << "failure\n"; // branch taken } { range_type r(foo, foo + 4); std::cout << r << std::endl; // <NeilGroves> // Now r has length 4 and std::string("foo") has length 3, correct branch taken // </NeilGroves> if (r == std::string("foo")) std::cout << "success\n"; else std::cout << "failure\n"; // branch taken // <NeilGroves> // "foo" has type char[4] and r is now of length 4 hence the correct branch is taken // </NeilGroves> if (r == "foo") std::cout << "success\n"; // branch taken else std::cout << "failure\n"; } } -- Bryce Lelbach aka wash boost-spirit.com px.cct.lsu.edu github.com/lll-project Literal strings are no longer intended to work as ranges. Literal string interoperability is provided via the as_literal function ( http://www.boost.org/doc/libs/1_46_1/libs/range/doc/html/range/reference/con...). Unfortunately it is not possible to stop this example compiling without breaking other valid uses of char arrays, since I cannot distinguish between a block of char, and a null-terminated string array. Boost.Range always interprets a char array as a block of chars and not as a null-terminated string. I hope this helps. Regards, Neil Groves
participants (3)
-
Bryce Lelbach
-
Mathias Gaunard
-
Neil Groves