代码之家  ›  专栏  ›  技术社区  ›  Zulan

std::chrono::duration和带有clang的自定义类型的运算符

  •  0
  • Zulan  · 技术社区  · 5 年前

    考虑一个自定义类型,该类型用于对持续时间的特定实例化进行乘除:

    #include <chrono>
    #include <iostream>
    
    class Foo {};
    
    using Duration = std::chrono::seconds;
    
    inline Duration operator*(Duration d, Foo) {
        std::cout << "multiplying some time with Foo\n";
        return d;
    }
    
    inline Duration operator/(Duration d, Foo) {
        std::cout << "dividing some time by Foo\n";
        return d;
    }
    
    int main() {
        Duration d;
        Foo f;
        d * f;
        d / f;
    }
    

    wandbox )

    In file included from prog.cc:1:
    /opt/wandbox/clang-7.0.0/include/c++/v1/chrono:1259:81: error: no type named 'type' in 'std::__1::common_type<long long, Foo>'
                              typename common_type<typename _Duration::rep, _Rep2>::type>::value>
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
    /opt/wandbox/clang-7.0.0/include/c++/v1/chrono:1272:7: note: in instantiation of default argument for '__duration_divide_imp<std::__1::chrono::duration<long long, std::__1::ratio<1, 1> >, Foo>' required here
        : __duration_divide_imp<duration<_Rep1, _Period>, _Rep2>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /opt/wandbox/clang-7.0.0/include/c++/v1/chrono:1279:10: note: in instantiation of template class 'std::__1::chrono::__duration_divide_result<std::__1::chrono::duration<long long, std::__1::ratio<1, 1> >, Foo, false>' requested here
    typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
             ^
    prog.cc:22:7: note: while substituting deduced template arguments into function template 'operator/' [with _Rep1 = long long, _Period = std::__1::ratio<1, 1>, _Rep2 = Foo]
        d / f;
    

    operator* 两种编译器都可以正常工作。

    问题类似于: User-defined overloaded operator * with std::chrono::duration

    0 回复  |  直到 5 年前
        1
  •  9
  •   Howard Hinnant    5 年前

    在我看来,这就像是一个libc++bug(也是我写的bug)。下面是一个非常简单的测试补丁:

    --- a/include/chrono
    +++ b/include/chrono
    @@ -1289,7 +1289,12 @@ struct __duration_divide_result<duration<_Rep1, _Period>, _Rep2, false>
     template <class _Rep1, class _Period, class _Rep2>
     inline _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR
    -typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
    +typename enable_if
    +<
    +    !__is_duration<_Rep2>::value &&
    +    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
    +    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
    +>::type
     operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
     {
         typedef typename common_type<_Rep1, _Rep2>::type _Cr;