从 std::complex<MyType> 到 std::complex<double> 的类型转换

Posted

技术标签:

【中文标题】从 std::complex<MyType> 到 std::complex<double> 的类型转换【英文标题】:Type conversion from std::complex<MyType> to std::complex<double> 【发布时间】:2020-04-29 08:40:58 【问题描述】:

我有一个类MyType,它实现了用户定义的算术类型。该类提供以下转换运算符

struct MyType 
 ...
  operator double()
   
    return to_double(); // This converts my type to a double value
  
... ;

如下使用这个类可以正常工作:

double d = MyType(1);

但是,在 std::complex 中使用此类作为类型,例如

#include <complex>
std::complex<double> c = std::complex<MyType>(1,1);

因以下编译器错误而失败:

error: conversion from 'std::complex<MyType>' to non-scalar type 'std::complex<double>' requested

感谢任何解决此问题的帮助。

马蒂亚斯

【问题讨论】:

【参考方案1】:

特化 std::complex&lt;float&gt;std::complex&lt;double&gt;std::complex&lt;long double&gt; 是用于表示和操作复数的 LiteralType。

为任何其他类型实例化模板复合体的效果是未指定的。

所以std::complex&lt;MyType&gt; 是“有问题的”...

忽略那部分,

std::complex&lt;T&gt; 具有通用转换构造函数,特化std::complex&lt;double&gt; 仅提供来自其他浮动复杂版本的转换。

operator= 允许对所有版本进行通用转换(尽管只有 Msvc 接受 code)。

您必须提供自己的(显式/命名)转换函数:

std::complex<double> to_complex_double(std::complex<MyType>& c)

#if 0
     std::complex<double> res;
     res = c; // gcc/clang doesn't accept that.
     return res;
#else
     return c.real(), c.imag();
#endif

【讨论】:

我重新阅读了文档,std::complex&lt;MyType&gt; 大多未指定... 我可以实现to_complex_double 转换函数,但这并不能解决我的问题,我猜。我想在 Eigen 库中使用它,该库在内部使用return static_cast&lt;NewType&gt;(x);,其中xconst std::complex&lt;MyType&gt;&amp;NewTypestd::complex&lt;double&gt;。是否有可能完成这项工作? 即使std::complex&lt;MyType&gt; 未被指定,主模板也不允许这样做。专门化std::complex&lt;MyType&gt; 将允许有预期的行为(不确定是否允许专门化std::complex&lt;MyType&gt; 而从what-can-and-cant-i-specialize-in-the-std-namespace,std::complex&lt;MyType&gt;不能特化。【参考方案2】:

这个(不是特别优雅的)解决方法有帮助吗?

std::complex<MyType> dummy(1,1);
std::complex<double> c1(
    static_cast<double>(dummy.real()), static_cast<double>(dummy.imag()));

我尝试了std::complex的各种不同的构造函数和赋值运算符,但没有找到更“隐式”的转换方式。

我认为这是相关的: Why doesn't a conversion function work with std::string?

【讨论】:

以上是关于从 std::complex<MyType> 到 std::complex<double> 的类型转换的主要内容,如果未能解决你的问题,请参考以下文章

在 boost::asio::buffer 中使用类似 std::vector<std::complex<double>> 的参数

在 C++ 中使用 std::complex<T> 创建复无穷大

使用 AVX2 高效计算 std::complex<float> 向量的绝对值

如何使用 SSE 加载 std::complex 数组的实部?

从 List<myType> 获取最大值

ObservableCollection<MyType>, MyType 上的扩展方法:IEnumerable<MyType>