C++ 向复杂类添加隐式提升,最后一步

C++ 向复杂类添加隐式提升,最后一步,c++,c++14,sfinae,C++,C++14,Sfinae,我希望在对复数求和时允许隐式转换。 例如: complex<double> a; complex<long double> b; int i; auto sum = a + b; // (1) auto SUM = a + i; // (2) 复合物a; 复合物b; int i; 自动求和=a+b;//(1) 自动求和=a+i;//(2) 我有代码,使转换(1)感谢答案 为了同时启用(2)转换,我使用了enable\u if\u t template

我希望在对复数求和时允许隐式转换。 例如:

 complex<double> a; 
 complex<long double> b;
 int i;

 auto sum = a + b; // (1)
 auto SUM = a + i; // (2)
复合物a;
复合物b;
int i;
自动求和=a+b;//(1)
自动求和=a+i;//(2)
我有代码,使转换(1)感谢答案 为了同时启用(2)转换,我使用了enable\u if\u 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});
  }
模板
自动运算符+(const::std::complex&a,std::enable_if_t&b)
{
typedef decltype(::std::declval()+::std::declval())组件;
typedef::std::复杂结果;
return::std::operator+(结果{a},结果{b});
}
然而,我得到一个编译错误,说“无法推断模板参数'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;
 }
模板
使用add_t=decltype(std::declval()+std::declval());
模板
自动操作员+(常数标准::复杂a、常数U和b)
->std::如果启用,则启用
{
std::complex res=a;
res+=b;
返回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)
}
#包括
#包括
模板
使用add_t=decltype(std::declval()+std::declval());
模板
constexpr std::complex运算符+(const std::complex&a,
const std::complex&b)无例外
{
使用returnType=decltype(a+b);
返回returnType(a.real()+b.real(),a.imag()+b.imag());
}
模板
constexpr std::complex运算符+(const std::complex&a,
康斯特U&b)无例外
{
使用returnType=decltype(a+b);
返回类型(a.real()+b,a.imag());
}
模板
constexpr自动运算符+(const T&a、const std::complex&b)无例外
{
返回b+a;//假定+运算符的交换性
}
使用名称空间std;
int main()
{
constexpr复合体a;
constexpr复合物b;
constexpr int i=1;
constexpr auto s1=a+b;//(1)
constexpr auto s2=a+i;//(2)
constexpr auto s3=i+a;//(3)
constexpr自动s4=a+2;//(4)
constexpr自动s5=2+a;/(5)
}

注意:它也适用于
constexpr
表达式。

请阅读“这需要C++14用于“自动”(也称为推导)返回类型。对于C++11,您基本上必须在返回类型的运算符中重复decltype表达式。”在其中一个答案中。我将C++14标志传递给编译器。我编辑了标签。谢谢你,你的解决方案看起来很优雅。但是,由于某种原因,它无法编译。@Federico缺少一个