[cfe-dev] Another esoteric libc++ issue: std::chrono::operator* SFINA

Gordon Henriksen gordonhenriksen at me.com
Thu Dec 20 10:08:15 PST 2012


This device fails for 'std::chrono::operator*', but not for '/'. '*' triggers an error if 'typename common_type<_Rep1, _Rep2>::type' is not valid; '/' sinks that constraint into a dependent type, letting the template be removed by SFINAE instead. My recollection is that the standard calls for the '/' behavior.

    #include <chrono>
    
    namespace {
        struct any {
            template<class T> any(const T &);
        };
        
        template<class A, class B>
        decltype(operator*(std::declval<A>(), std::declval<B>()),
                 std::true_type())
        help_are_multiplicable(A, B);
        
        std::false_type
        help_are_multiplicable(any, any);
        
        template<class A, class B>
        class are_multiplicable : public decltype(
            help_are_multiplicable(std::declval<A>(), std::declval<B>())
        ) { };
    }
    
    static_assert(!are_multiplicable<std::chrono::seconds,
                                     std::chrono::seconds>::value,
                  "fails"); // expect-error

This implementation may be useful as reference:

    template<typename D, typename R,
             bool Arith = carbonite::is_arithmetic<R>::value>
    struct dur_rep_mul_result_type_ : public enable_if2<false> { };
    
    template<typename DR, typename DP, typename R>
    struct dur_rep_mul_result_type_<duration<DR,DP>,R,true> : public enable_if2<
        carbonite::is_convertible<
            R,typename carbonite::common_type<DR,R>::type
        >::value,
        duration<typename carbonite::common_type<DR,R>::type,DP>
    > { };
    
    template<typename R1, typename P, typename R2>
    typename dur_rep_mul_result_type_<duration<R1,P>,R2>::type
    operator*(const duration<R1,P> &d, const R2 &s);
    
    template<typename R1, typename P, typename R2>
    typename dur_rep_mul_result_type_<duration<R2,P>,R1>::type
    operator*(const R1 &s, const duration<R2,P> &d);

-- Gordon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: chrono-mul-sfinae.cpp
Type: application/octet-stream
Size: 1080 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121220/ec59527b/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Makefile
Type: application/octet-stream
Size: 101 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121220/ec59527b/attachment-0001.obj>


More information about the cfe-dev mailing list