|
Boost : |
Subject: Re: [boost] [range] strange behavior of operator== with iterator_range
From: Neil Groves (neil_at_[hidden])
Date: 2011-05-18 19:22:23
On Wed, May 18, 2011 at 9:25 PM, Bryce Lelbach <blelbach_at_[hidden]> 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/overview.html
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/concept_implementation/semantics/functions.html). 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk