Boost logo

Boost :

Subject: Re: [boost] [Proto] Errors due to narrowing conversions in matches.hpp
From: Eric Niebler (eric_at_[hidden])
Date: 2012-04-22 02:29:06

On 4/21/2012 10:22 PM, Michel Morin wrote:
> Eric Niebler wrote:
>>> Some tests of Boost.Phoenix fail on clang trunk in a C++11 mode
>>> due to narrowing conversions of non-type template arguments,
>>> which are prohibited in C++11.
>> Really?! Wow, that's a breaking change I hadn't heard of before.
> Let me elaborate a bit.
> On clang-cxx11-r155296 test runner,
> ( )
> there are many failures due to the following errors.
> boost/proto/matches.hpp:354:17:
> error: non-type template argument evaluates to 2,
> which cannot be narrowed to type 'bool' [-Wc++11-narrowing]
> boost/proto/matches.hpp:363:21:
> error: non-type template argument evaluates to 2,
> which cannot be narrowed to type 'bool' [-Wc++11-narrowing]
> The problem is that
> remove_reference<
> typename when<_, If>::template impl<Expr, int, int>::result_type
> >::type::value
> evaluates to "2", which is not in the range of bool.
> This causes the compiler errors.

I'm trying to understand why it doesn't evaluate to a bool, because it
should. The fact that it doesn't may indicate a bug in Phoenix or some
other library. Since I have never been able to get clang to work on
Windows (hello, clang team!), I had to resort to eyeballing Phoenix,
which let me to the oddness in is_placeholder.

>> Ideally, this should be a valid MPL Integral Constant of type bool, like:
>> template< class T >
>> struct is_placeholder
>> : mpl::false_
>> {};
>> If that is not portable enough, it could be:
>> template< class T > struct is_placeholder
>> {
>> BOOST_STATIC_CONSTANT(bool, value = false);
>> };
> Neither of them solve the problem.
> After applying the proposed change, we still have the same errors.

I looked a bit deeper and found the problem in boost/bind/arg.hpp.
There, is_placeholder is specialized for arg<I> to have a value of I,
the placeholder number. Despite its name, is_placeholder is *not* a
boolean metafunction! C++11 defines std::is_placeholder similarly. It's
a naming issue. Bizarre. <Thinking...> Adding the static_cast like you
suggest is probably the right fix.

Btw, many thanks for helping to flush out and track down these problems.

Eric Niebler
BoostPro Computing

Boost list run by bdawes at, gregod at, cpdaniel at, john at