用户定义的重载运算符 * 与 std::chrono::duration

2024-01-10

我创建了一个频率类模板,旨在与std::chrono::持续时间 http://en.cppreference.com/w/cpp/chrono/duration。频率对象存储每单位持续时间的周期数(均使用其类型的模板参数)。这个想法是,将频率乘以持续时间会生成 Rep 类型的对象。这是类定义。除了相关成员之外,我省略了所有成员。

#include <ratio>
#include <chrono>
using namespace std::chrono;

template <typename Rep, typename Period = std::ratio<1>>
class Frequency
{
public:
    explicit Frequency(Rep cycles) : _cycles{cycles} { }

    friend Rep operator *(const Frequency<Rep, Period>& f, const duration<Rep, Period> d)
    {
        return f._cycles * d.count();
    }
    friend Rep operator *(const duration<Rep, Period> d, const Frequency<Rep, Period>& f)
    {
        return f._cycles * d.count();
    }
private:
    Rep _cycles; ///> The number of cycles per period.
};

问题(我认为)是 std::chrono::duration 也会重载 * 运算符,如下所示:

template< class Rep1, class Period, class Rep2 >
duration<typename std::common_type<Rep1,Rep2>::type, Period>
    constexpr operator*( const duration<Rep1,Period>& d,
                         const Rep2& s );

template< class Rep1, class Rep2, class Period >
duration<typename std::common_type<Rep1,Rep2>::type, Period>
    constexpr operator*( const Rep1& s,
                         const duration<Rep2,Period>& d );

根据参考参数 http://en.cppreference.com/w/cpp/chrono/duration,这些方法中的每一个

将持续时间 d 转换为 Rep 为 Rep1 和 Rep2 之间通用类型的持续时间,并将转换后的刻度数乘以 s。

我相信编译器正在尝试使用这些重载的运算符模板而不是我的重载。当我编写以下代码时:

Frequency<double> f{60.0};
duration<double> d{1.0};
double foo = f * d;

我在 VS2013 中遇到类似以下错误:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\type_traits(1446) : error C2446: ':' : no conversion from 'double' to 'Frequency<double,std::ratio<0x01,0x01>>'
        Constructor for class 'Frequency<double,std::ratio<0x01,0x01>>' is declared 'explicit'
        source_file.cpp(27) : see reference to class template instantiation 'std::common_type<Frequency<double,std::ratio<0x01,0x01>>,Rep>' being compiled
        with
        [
            Rep=double
        ]

第1446行是VS的实现std::common_type.

那么,有没有办法确保调用我的重载而不是 std::chrono::duration 中的重载?我知道我可以通过不使用运算符重载并编写不同名称的方法来解决问题,但如果可能的话,我想更好地了解这里发生的情况。 (而且重载更方便。)

另外,如果这个问题重复,我深表歉意,但搜索后我找不到类似的内容。


在此代码中:

Frequency<double> f{60.0};
duration<double> d{1.0};
double foo = f * d;

编译器说“哦,我必须找到一个operator*这需要一个Frequency<double> and a std::chrono::duration<double>. What operator*有没有可能?它会生成一个可能性列表,主要由以下两种组成:

friend Rep operator *(const Frequency<Rep, Period>& f, const duration<Rep, Period> d)
{
    return f._cycles * d.count();
}

template< class Rep1, class Rep2, class Period >
duration<typename std::common_type<Rep1,Rep2>::type, Period>
constexpr operator*( const Rep1& s,
                     const duration<Rep2,Period>& d );

然后,它试图找出exactly每个签名是什么。第一个是:

Rep operator *(const Frequency<Rep, Period>& f, const duration<Rep, Period> d)

并尝试第二个结果:

error C2446: ':' : no conversion from 'double' to 'Frequency<double,std::ratio<0x01,0x01>>'
        Constructor for class 'Frequency<double,std::ratio<0x01,0x01>>' is declared 'explicit'
        source_file.cpp(27) : see reference to class template instantiation 'std::common_type<Frequency<double,std::ratio<0x01,0x01>>,Rep>' being compiled

因为它甚至无法弄清楚签名是什么is,它无法弄清楚该选择哪一个,然后就放弃了。我认为这是 MSVC 实现中的一个错误operator*在这种情况下。

明显的解决方法是使common_type<Frequency<double>,Rep>能够编译,可能通过删除explicit对构造函数的限制。阿舍普勒 https://stackoverflow.com/users/459640/aschepler观察到专业化可能更聪明、更有用common_type:

namespace std {
    template <typename Rep, typename Period>
    struct common_type<Frequency<Rep,Period>, std::chrono::duration<Rep,Period>>   
    {
        typedef Rep type;
    };
    template <typename Rep, typename Period>
    struct common_type<std::chrono::duration<Rep,Period>, Frequency<Rep,Period>>   
    {
        typedef Rep type;
    };
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用户定义的重载运算符 * 与 std::chrono::duration 的相关文章

  • 从数组中输入多个数字,每个数字检查是否为整数

    每个人 我希望有人能帮我弄清楚C语言的一些东西 这是我第一次认真地做IT方面的作业 我没有经验 而且我正在电子学习中学习 所以老师的帮助不是很好 我需要用C语言开发控制台应用程序 用户需要输入10个整数 如果插入的数字不是整数 需要输出错误
  • 委托和接口如何互换使用?

    我可以使用接口方法代替委托吗 如何 我发现搜索接口方法比使用委托更快 我希望有一个简单的代码片段 理论上 可以通过包含单个方法的接口 例如 Java 没有委托 来完成委托完成的所有工作 然而 它使代码变得更加冗长并且没有带来什么好处 话又说
  • 如何在 C# 中启动文件

    编辑 我觉得自己像个白痴 我有一种感觉 像下面的答案会起作用 但没有看到任何与下面的答案类似的谷歌结果 所以当我看到这段复杂的代码时 我想它一定是这样的 我搜索并找到了这个Windows 列出并启动与扩展关联的应用程序 https stac
  • OpenGL,如何独立旋转对象?

    到目前为止我的代码 void display void glClear GL COLOR BUFFER BIT GL DEPTH BUFFER BIT Clear Screen And Depth Buffer glLoadIdentity
  • 如何使用 C# 调用 REST API?

    这是我到目前为止的代码 public class Class1 private const string URL https sub domain com objects json api key 123 private const str
  • WCF 客户端返回空数组 - XML 响应似乎正常

    我正在尝试为我们的 Intranet 上托管的 Web 服务创建一个简单的 WCF 客户端 C 使用 Fiddler 和 SoapUI 我可以看到请求和响应似乎正常 但是当我运行代码时返回一个空数组 我会尝试只粘贴相关的行 但会是很多东西
  • C++ 为非虚方法指定初始化

    我有 a h 如下所示 class A public void doSomething 0 然后我有 b h 如下所示 include a h class b public A public void doSomething 我只是想通过尝
  • 如何设置cookie值?

    我正在执行以下操作来设置 cookie 值 HttpCookie mycookie new HttpCookie mycookie mycookie Value value1 Case sensitivity mycookie Expire
  • C++ fill() 与 uninitialized_fill()

    您好 我是初学者 我想知道容器的 fill 和 uninitialized fill 之间的区别 我在谷歌上进行了快速搜索 但没有得到很好的答案 有人可以帮助我吗 fill 将值 使用赋值运算符 分配给已构造的对象 uninitialize
  • Roslyn,通过 hostObject 传递值

    我正在尝试通过 hostObject 发送一个类 但显然它不想工作 using Roslyn Compilers using Roslyn Compilers CSharp using Roslyn Scripting using Rosl
  • 如何将此 Boost ASIO 示例应用到我的应用程序中

    我已经阅读了很多 ASIO 示例 但我仍然对如何在我的应用程序中使用它们感到困惑 基本上 我的服务器端需要接受超过100个连接 客户端 这部分是通过使用线程池 通常每个CPU核心2 4个线程 来完成的 为简单起见 我们假设只有一个连接 为了
  • 我们可以使用 C# 录制发送到扬声器的声音吗

    我有一个软件 SoundTap Streaming Audio Recorder 它记录发送到扬声器的任何音频 无论流是来自网络还是来自某些文件或麦克风 我可以在桌面应用程序中制作这样的应用程序 以便我可以录制发送到扬声器的流 无论来源如何
  • 在 C++17 中编译具有非固定基础类型的 constexpr 从 int 静态转换为作用域枚举的未定义行为

    我想知道以下内容是否应该在 C 17 中编译 enum class E A B constexpr E x static cast
  • 定义一个断言,即使定义了 NDEBUG,该断言也有效

    我想定义一个assert与标准相同的宏assert 3 http man7 org linux man pages man3 assert 3 html调用 但它不会被预处理器删除NDEBUG被定义为 这样的呼唤 让我们称之为assert2
  • 具有两个表的谓词构建器

    A Party可以有一个或多个Contact对象 我想选择全部Parties谁的街道名称包含特定关键字 如果我只想搜索Party我可以使用下面的代码 但我如何扩展它来搜索Contact public IQueryable
  • 在 Visual Studio C++ 资源编辑器中导入 png 文件

    我希望能够在 Visual Studio 资源编辑器中导入 png 文件 以便能够在不同的其他项目中使用嵌入的资源 有解决办法吗 我知道它适用于位图 但我对 png 感兴趣 因为即使在较低格式 16x16 或 32x32 上也可以使用 透明
  • 致命:所有操作都需要OperationId。请为路径的“获取”操作添加它

    我正在使用 AutoRest 从 swagger json 生成 api 的客户端 输出是 AutoRest code generation utility cli version 3 0 6187 node v10 16 3 max me
  • 返回右值 - 这段代码有什么问题? [复制]

    这个问题在这里已经有答案了 我遇到了以下代码片段 std string test std string m Hello return std move m int main std string m test 我知道上面的代码是不正确且不安
  • 使用 Powershell 或 C# 获取 Azure“文件和文件夹”作业状态

    我一直在尝试找到一种方法来获取在 AzureRM 中运行的几个客户上运行的 文件和文件夹 备份作业的状态 可以在 AzureRm 门户中手动找到状态 恢复服务保管库 gt 作业 gt 备份作业 使用powershell不显示任何作业信息 G
  • “while(true) { Thread.Sleep }”的原因是什么?

    我有时会遇到以下形式的代码 while true do something Thread Sleep 1000 我想知道这是否被认为是好的做法还是坏的做法以及是否有任何替代方案 通常我在服务的主函数中 找到 这样的代码 我最近在 Windo

随机推荐