不匹配的类型:'std::chrono::_V2::steady_clock' 和 'std::chrono::_V2::system_clock'。

3

我正试图在 mingw64 (GCC v11.2) 中构建我的程序。我有以下的 struct:

在一个头文件中:

struct Timer
{
    std::chrono::time_point< std::chrono::steady_clock > start;
    std::chrono::time_point< std::chrono::steady_clock > end;

    Timer( );
    ~Timer( );
};

在源代码文件中:

util::Timer::Timer( )
: start( std::chrono::high_resolution_clock::now( ) )
{
}

util::Timer::~Timer( )
{
    end = std::chrono::high_resolution_clock::now( );
    std::chrono::duration< double, std::milli > duration_ms { end - start };
    std::clog << "\nTimer took " << duration_ms.count( ) << " ms\n";
}

但是发生了这种情况:

error: no matching function for call to 'std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long long int, std::ratio<1, 1000000000> > >::time_point(std::chrono::_V2::system_clock::time_point)'
    8 | : start( std::chrono::high_resolution_clock::now( ) )
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from pch.h:23:
c:\mingw64\include\c++\11.2.0\chrono:871:21: note: candidate: 'template<class _Dur2, class> constexpr std::chrono::time_point<_Clock, _Dur>::time_point(const std::chrono::time_point<_Clock, _Dur2>&) [with _Dur2 = _Dur2; <template-parameter-2-2> = <template-parameter-1-2>; _Clock = std::chrono::_V2::steady_clock; _Dur = std::chrono::duration<long long int, std::ratio<1, 1000000000> >]'
  871 |           constexpr time_point(const time_point<clock, _Dur2>& __t)
      |                     ^~~~~~~~~~
c:\mingw64\include\c++\11.2.0\chrono:871:21: note:   template argument deduction/substitution failed:
Util.cpp:8:3: note:   mismatched types 'std::chrono::_V2::steady_clock' and 'std::chrono::_V2::system_clock'
    8 | : start( std::chrono::high_resolution_clock::now( ) )
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

为什么会出现这种情况?如何解决?

4
请注意,std::chrono::steady_clockstd::chrono::high_resolution_clock并不相同(必须区分)。不能混用它们。 - Paul Sanders
正如@PaulSanders所说,编译器是正确的。然而,这段代码在clang(带有libc ++)和MSVC中可以编译 - https://godbolt.org/z/ddb5Mxcv9 - Richard Critten
6
high_resolution_clocksteady_clock 或者 system_clock 的别名。具体使用哪个取决于实现,而且甚至会因版本不同而改变。 - NathanOliver
3
为什么不将 startend 改为 std::chrono::time_point<std::chrono::high_resolution_clock>?或者使用 std::chrono::steady_clock::now()?基本上,不要混合它们。 - Kevin
1
请查看此处的注释:https://en.cppreference.com/w/cpp/chrono/high_resolution_clock - Jesper Juhl
显示剩余3条评论
1个回答

3
感谢评论中提供的信息,我得到了以下解决方案:
在头文件中:
struct Timer
{
    std::chrono::time_point< std::chrono::steady_clock > start;
    std::chrono::time_point< std::chrono::steady_clock > end;

    Timer( );
    ~Timer( );
};

在源文件中:
util::Timer::Timer( )
: start( std::chrono::steady_clock::now( ) )
{
}

util::Timer::~Timer( )
{
    end = std::chrono::steady_clock::now( );
    std::clog << "\nTimer took " << std::chrono::duration< double, std::milli >( end - start ).count( ) << " ms\n";
}

简而言之,我从std::chrono::high_resolution_clock::now( )切换到std::chrono::steady_clock::now( ),因为根据high_resolution_clock,不同编译器实现的high_resolution_clock有所不同。
其中一些编译器返回std::chrono::time_point<std::chrono::steady_clock>,另一些则返回std::chrono::time_point<std::chrono::system_clock>。这给我造成了问题。 cppreference的一则注释: 高分辨率时钟在不同的标准库实现中没有一致的实现方法,应该尽量避免使用它。它通常只是std::chrono::steady_clock或std::chrono::system_clock的别名,但它是哪一个取决于库或配置。当它是system_clock时,它不是单调的(例如,时间可能会倒流)。例如,对于gcc的libstdc++,它是system_clock;对于MSVC,它是steady_clock;对于clang的libc++,它取决于配置。通常,应该直接使用std::chrono::steady_clock或std::chrono::system_clock,用于持续测量和挂钟时间。

将此标记为您自己的答案会很棒。 - Marco A.
@Marco 已完成 :) - digito_evo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接