Re: [Boost-bugs] [Boost C++ Libraries] #10853: problem with detection of const_cast_from

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #10853: problem with detection of const_cast_from
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-12-05 21:16:03


#10853: problem with detection of const_cast_from
------------------------------------+------------------------
  Reporter: Matei David <matei@…> | Owner: igaztanaga
      Type: Bugs | Status: new
 Milestone: To Be Determined | Component: intrusive
   Version: Boost 1.57.0 | Severity: Problem
Resolution: | Keywords:
------------------------------------+------------------------

Comment (by Matei David <matei@…>):

 I've isolated the heart of the problem. The attached file demonstrates how
 overload resolution fails with 2 non-template candidate functions, when
 both involve non-trivial constructor calls, even though one of them
 involves ellipses. I imagine the original detection code in
 `boost/intrusive/detail/has_member_function_callable_with.hpp` assumed the
 compiler would prefer the non-ellipses constructor.

 The bug is triggered in the boost intrusive library as follows:
 1. In the docs, the signature for `list_node_traits::get_next()` is:
 {{{
 static node_ptr get_next(const_node_ptr)
 }}}
 2. In `list::front() const`, the following code appears:
 {{{
 detail::uncast(node_traits::get_next(this->get_root_node()))
 }}}
 3. As a result, `detail::uncast()` is called with an argument of type
 `node_ptr` (not `const_node_ptr`!).
 4. In turn, this triggers the mechanism looking for:
 {{{
 node_ptr::const_cast_from(const node_ptr&)
 }}}
 5. The documentation doesn't specify such a method should exist. One would
 assume it is ok to only have a similar function where the argument is
 `const_node_ptr` (not `node_ptr`!):
 {{{
 node_ptr::const_cast_from(const const_node_ptr&)
 }}}
 6. The existing code tries to detect `const_cast_from` by passing it an
 argument of type `declval<node_ptr>()`.
 7. Naturally, a constructor exists with the signature:
 {{{
 const_node_ptr(const node_ptr&)
 }}}
 8. However, the overload resolution code now has to choose between calling
 the constructor above, or the ellipses constructor from
 `has_member_function_callable_with.hpp:191`.
 9. As the small example demonstrates, the resolution fails with a compile-
 time error.

 Possible fixes:
 * Update the docs to make it clear `node_ptr::const_cast_from(const
 node_ptr&)` should exist. It can be either a normal function, or a
 template specialization. But crucially, it may not involve extra
 constructor calls that might confuse overload resolution.
 * Fix the intrusive code to not run unnecessary `const_cast_from`
 detection, i.e., when the argument is already a pointer to a non-const
 object. This is hard, because it's unclear where to look.
 * More robust `const_cast_from` detection.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/10853#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:17 UTC