Opened 19 years ago

Closed 19 years ago

Last modified 19 years ago

#244 closed Bugs (None)

Bug in lexical_cast.hpp

Reported by: jfmeinel Owned by: kevlin
Milestone: Component: lexical_cast
Version: None Severity:
Keywords: Cc:

Description

In boost-1_31_0, I believe there is a typo in
lexical_cast.hpp

The line
    Target lexical_cast(Source arg)
should be
    Target lexical_cast(Source& arg)

Otherwise it actually creates a copy of the argument
before doing the lexical cast.
This causes problems if you try to lexical_cast() a
virtual object.
Here is code that shows the bug. By just adding the
'&', the code performs as you would expect it to.

#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>

struct A { virtual int f() const = 0; };

struct B : A { virtual int f() const { return 1; } }; 

struct C : B { virtual int f() const { return 2; } };

std::ostream& operator<<(std::ostream& os, const A& a) {
  return os << a.f();
}

int main()
{
  C c; std::string s;
  std::cout << c << std::endl; //This should print 2
  s = boost::lexical_cast<std::string>(c);
  std::cout << s << std::endl; //This should print 2
  s = boost::lexical_cast<std::string, B>(c);
  std::cout << s << std::endl; //This returns 1, not 2
  //This fails because it tries to instantiate an
object of type A. Why???
  s = boost::lexical_cast<std::string, A>(c);
  std::cout << s << std::endl;
}

Change History (2)

comment:1 by kevlin, 19 years ago

Status: assignedclosed
Logged In: YES 
user_id=32864

The pass-by-copy has always been intentional and is not a
defect. 

comment:2 by jfmeinel, 19 years ago

Logged In: YES 
user_id=266114

Is there a discussion about this that I can read? I use
boost::python, and the built-in str() function uses lexical
cast to convert your object to a string. However, this
ignores virtual functions, and doesn't allow lexical casts
of abstract base classes. I realize there are possibly some
dependencies on <limits> (which also requires non-abstract
class), but are those actually necessary?
I thought all you really needed defined was the << operator,
and lexical_cast should work.
Note: See TracTickets for help on using tickets.