gpt4 book ai didi

C++ 转换运算符到 chrono::duration - 适用于 c++17 但不适用于 C++14 或更低版本

转载 作者:可可西里 更新时间:2023-11-01 17:20:46 28 4
gpt4 key购买 nike

以下代码使用设置为 C++17 的 gcc 7.1.0 进行编译,但不使用设置为 C++14(或 Visual Studio 2017)进行编译。在 Wandbox 上很容易重现.

要让它与 C++11/14 一起工作,必须做些什么?

#include <iostream>
#include <chrono>

int main()
{
struct Convert
{
operator std::chrono::milliseconds()
{
std::cout << "operator std::chrono::milliseconds" << std::endl;
return std::chrono::milliseconds(10);
}

operator int64_t ()
{
std::cout << "operator int64_t" << std::endl;
return 5;
}
};

Convert convert;

std::chrono::milliseconds m(convert);
std::cout << m.count() << std::endl;
int64_t i(convert);
std::cout << i << std::endl;
}

最佳答案

让我们从为什么这在 C++14 中不起作用开始。 std::chrono::duration有两个相关的c'tors (std::chrono::milliseconds 的别名是):

duration( const duration& ) = default;

template< class Rep2 >
constexpr explicit duration( const Rep2& r );

模板化的参数更适合 Convert 类型的参数。但只有当 Rep2(又名 Convert)可隐式转换为 std::chrono::duration 的表示类型时,它才会参与重载决议.对于毫秒,在Wandbox 上是long。您的 int64_t 转换运算符使隐式转换成为可能。

但这就是陷阱。对此隐式转换的检查不考虑转换成员函数的 cv 限定符。因此选择了重载,但它通过 const 引用接受。并且您的用户定义的转换运算符不是 const 合格的! @Galik在您的帖子的评论中注明。因此,转换在 毫秒 的c'tor 内失败。

那么如何解决呢?两种方式:

  1. 将转换运算符标记为const。然而,这将为 mi 选择转换为 int64_t

  2. 将到 int64_t 的转换标记为 explicit。现在,模板化重载不会参与 m 的重载决策。

最后,为什么这在 C++17 中有效?那将保证复制省略。由于您的 Convert 具有到 std::chrono::milliseconds 的转换,因此它直接用于初始化 m。它的细节包括甚至不需要选择复制构造函数,只是稍后将其删除。

关于C++ 转换运算符到 chrono::duration - 适用于 c++17 但不适用于 C++14 或更低版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48365690/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com