将隐式促销添加到复杂类,最后一步

Add implicit promotion to complex class, last step

本文关键字:复杂 最后一步 添加      更新时间:2023-10-16

我想在求和时允许隐式转换。例如:

 complex<double> a; 
 complex<long double> b;
 int i;
 auto sum = a + b; // (1)
 auto SUM = a + i; // (2)

我的代码可以启用转换(1),这要归功于回答隐式类型的促销。为了启用(2)转换,我使用了enable_if_t

  template <typename T, typename U>
  auto operator +(const ::std::complex<T> &a,     std::enable_if_t<std::is_arithmetic<U>::value, U>  &b) 
  {
   typedef decltype(::std::declval<T>() + ::std::declval<U>()) comcomp_t;
   typedef ::std::complex<comcomp_t> result_t;
   return ::std::operator +(result_t{a}, result_t{b});
  }

但是,我遇到了一个汇编错误,说"无法推断模板paramter'u'。我猜我对Sfinae的理解非常浅。任何帮助都将不胜感激。谢谢

第二个参数是未建立的上下文。您必须重写此功能,以便实际推导U。典型的方法是将Sfinae粘贴到返回类型中。

 template <typename T, typename U>
 using add_t = decltype(std::declval<T>() + std::declval<U>());
 template <typename T, typename U>
 auto operator+(const std::complex<T>& a, const U& b)
     -> std::enable_if_t<std::is_arithmetic<U>::value,
                         std::complex<add_t<T, U>>>
 {
     std::complex<add_t<T, U>> res = a;
     res += b;
     return res;
 }

我不确定您在这里需要Sfinae。最小工作C 14代码是:

#include <ccomplex>
#include <type_traits>
template <typename T, typename U>
using add_t = decltype(std::declval<T>() + std::declval<U>());
template <typename T, typename U>
constexpr std::complex<add_t<T, U>> operator+(const std::complex<T>& a,
                                              const std::complex<U>& b) noexcept
{
  using returnType = decltype(a + b);
  return returnType(a.real() + b.real(), a.imag() + b.imag());
}
template <typename T, typename U>
constexpr std::complex<add_t<T, U>> operator+(const std::complex<T>& a,
                                              const U& b) noexcept
{
  using returnType = decltype(a + b);
  return returnType(a.real() + b, a.imag());
}
template <typename T, typename U>
constexpr auto operator+(const T& a, const std::complex<U>& b) noexcept
{
  return b + a;  // assume commutativity of + operator
}
using namespace std;
int main()
{
  constexpr complex<double> a;
  constexpr complex<long double> b;
  constexpr int i = 1;
  constexpr auto s1 = a + b;  // (1)
  constexpr auto s2 = a + i;  // (2)
  constexpr auto s3 = i + a;  // (3)
  constexpr auto s4 = a + 2;  // (4)
  constexpr auto s5 = 2 + a;  // (5)
}

注意:它也与constexpr表达式一起使用。