Subject: [Boost-bugs] [Boost C++ Libraries] #9910: is_convertible doesn't compile with inaccessible copy constructor
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-04-15 15:47:38
#9910: is_convertible doesn't compile with inaccessible copy constructor
-----------------------------------+-------------------------
Reporter: Matei David <matei@â¦> | Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: type_traits
Version: Boost 1.55.0 | Severity: Problem
Keywords: is_convertible |
-----------------------------------+-------------------------
I found a situation where (with `gcc-4.8.2` & `boost-1.55`) I cannot
compile a call to `boost::is_convertible`, but I can compile a similar
call to `std::is_convertible`. This is a bug, unless it is undefined
behaviour to pass `is_convertible` a type with a private or deleted copy
constructor. If it is a bug, it is a `boost` bug, not a `gcc` bug
(explained below).
Here is the discordant code:
{{{
#include <type_traits>
#include <boost/type_traits/is_convertible.hpp>
struct A {
A() = default;
A(const A&) = delete; // or private: A(const A&) = default;
};
struct Ref_A { // proxy reference to A
operator A& () { return *_ptr; }
A* _ptr;
};
int main() {
(void)std::is_convertible< Ref_A, A >::value;
(void)boost::is_convertible< Ref_A, A >::value;
}
}}}
I compile with:
`{g++|clang++} -std=c++11 -I${BOOST_INCLUDE} -Wall -Wextra -c`
With `gcc-4.8.2`, the call to `boost::is_convertible` fails to compile,
complaining that the copy constructor of A is deleted (or private.) The
similar call to `std::is_convertible` compiles ok (and returns false, but
that is irrelevant).
With `clang-3.4`, both calls compile. The reason for the discrepancy is
that `boost/type_traits/intrinsics.hpp` defines the macro
`BOOST_IS_CONVERTIBLE(T,U)` for `clang`, but not for `gcc`. Because of
that, at the bottom of `boost/type_traits/is_convertible.hpp`, `clang`
uses the macro to implement `is_convertible`, whereas `gcc` uses
`is_convertible_impl_dispatch` instead (which is the one that fails).
That's why I said this is not a `gcc` bug.
A temporary fix I found is to define that macro to defer to `std`:
{{{
#include <type_traits>
#include <boost/type_traits/intrinsics.hpp>
#ifndef BOOST_IS_CONVERTIBLE
#define BOOST_IS_CONVERTIBLE(T, U) (std::is_convertible<T, U>::value)
#endif
#include <boost/type_traits/is_convertible.hpp>
}}}
Which `type_traits` library should we prefer these days, post `c++11`?
Intuition says `std` should be more stable/portable, is that wrong? If it
is indeed `std`, is there a way (perhaps a macro?) to make `boost` mirror
`std` (I'm talking about `type_traits` only). The reason for having such a
mirror option is not for new code, but for other `boost` libraries which
need `type_traits`. E.g, I came across this issue from `boost::iterator`.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/9910> 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:16 UTC