Boost logo

Boost :

Subject: Re: [boost] [config] gcc-4.4 and BOOST_NO_SFINAE_EXPR
From: Eric Niebler (eric_at_[hidden])
Date: 2012-09-24 14:15:49


On 9/24/2012 8:33 AM, John Maddock wrote:
>>>> As part of our work to make result_of sfinae-friendly, Daniel Walker
>>>> and
>>>> I have discovered that gcc-4.4 doesn't have very good support for
>>>> generalized sfinae for expressions.
>>>
>>> Then, wouldn't it be nice to ask gcc developers to change the
>>> availability of "Solving the SFINAE problem for expressions"
>>> from gcc 4.4 to gcc 4.5 in http://gcc.gnu.org/projects/cxx0x.html ?
>>
>> Shouldn't whether this macro is defined or not depend on whether the
>> associated test fails or succeeds, rather than what the compiler
>> claims to support?
>
> Ideally, yes that should always be the case. It's always a bit tricky
> knowing where to draw the line when the feature works "most of the time"
> but fails in tricky cases.
>
>> If the test is not strict enough, it could be modified.
>
> Patches welcome.
>
> Also, if the test does actually pass for compiler X but we define the
> defect macro anyway because enough real world cases fail, then there
> should be a comment in the config file for that compiler stating why the
> macro is set. Otherwise some helpful person will likely unset the macro
> in future ;-)

I confess to not understanding how the config tests work. When I run
"bjam toolset=gcc-4.4 config_test" in libs/config/tests, the tests pass
whether or not BOOST_NO_SFINAE_EXPR is defined for gcc-4.4. I'm clearly
doing something wrong.

Anyway, here is a test for sfinae-expr that fails with gcc-4.4:

    template<typename T> T declval();

    struct not_incrementable {};

    struct inc {
        template<typename T>
        auto operator()(T t) const -> decltype(t++)
            { return t++; }
    };

    template<typename T>
    struct wrap
    {};

    template<typename A>
    int try_inc(wrap<decltype(declval<inc>()(declval<A>()))> *) {
        return 0;
    }

    template<typename A>
    not_incrementable try_inc(...) {
        return not_incrementable();
    }

    struct X {};

    int main() {
        int x = try_inc<int>(0); // OK
        not_incrementable y = try_inc<X>(0); // OK, not_incrementable
    }

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk