C++ 派生类的重载解析失败

C++ 派生类的重载解析失败,c++,templates,operator-overloading,overloading,overload-resolution,C++,Templates,Operator Overloading,Overloading,Overload Resolution,我使用的是mArray类,它实现了具有可变维度的数字数据容器 template <typename T> class mArray<T>: { ... std::vector<T> my_data; } (getSizes()是一个mArray函数) 但是现在我的代码从文件中加载了一个mDcmImage,当我使用 typedef int intensity; mDcmImage<intensity> im1 ("/

我使用的是mArray类,它实现了具有可变维度的数字数据容器

template <typename T>
   class mArray<T>: {
     ...
     std::vector<T> my_data;
   }
getSizes()
是一个
mArray
函数)
但是现在我的代码从文件中加载了一个
mDcmImage
,当我使用

typedef int intensity;
mDcmImage<intensity> im1 ("/tmp/test1.im");
mDcmImage<intensity> im2 ("/tmp/test2.im");
im1 += im2;
typedef int强度;
mDcmImage im1(“/tmp/test1.im”);
mDcmImage im2(“/tmp/test2.im”);
im1+=im2;
然后我得到以下错误:

mArray.hpp required from ‘struct mArray<T>::operator+=(const U&) 
           [with U = mDcmImage<int>; T = int]::<lambda(const int&)>’|
mArray.hpp required from ‘void mArray<T>::operator+=(const U&) 
           [with U = mDcmImage<int>; T = int]’|
  test.cpp required from here|
mArray.hpp error: no match for ‘operator+’ in ‘lhs + rhs’|
“struct mArray::operator+=(const U&)需要mArray.hpp [带U=mDcmImage;T=int]:'| “void mArray::operator+=(常量U&)中需要mArray.hpp [带U=mDcmImage;T=int]'| 此处需要test.cpp| mArray.hpp错误:“lhs+rhs”中的“operator+”不匹配| 换句话说:尽管我对另一个
mArray
的加法以及一个值的加法进行了编码,但当我调用主程序中的
+=
操作符将两个数组相加时,它使用
+=
实现来实现单个值

我试过几种方法,例如

  • 运算符+=
    的值版本使用
    std::enable_if::type*
    ——不允许,因为
    运算符+=
    严格采用1个参数
  • 同时为
    mImage
    mDcmImage
    定义
    operator+=
    的两个版本——在这些级别上,它也使用了错误的实现

在a中,选择了运算符的正确版本为什么现在不选择?我不明白为什么重载解析在这里失败

在模板参数推导后,第二个版本成为完美匹配:

template <typename U> void operator+= (const U& rhs); // U = mDcmImage<int>
因此,它是通过过载分辨率选择的


最简单的修复方法可能是修改单值版本,使其仅采用
T
并依赖隐式转换:

void operator+= (const T& rhs);
SFINAE也是可能的,例如在返回类型中:

template <typename U> 
typename std::enable_if<std::is_arithmetic<U>::value>::type operator+= (const U& rhs);
模板
typename std::enable_if::type operator+=(常量U&rhs);

为什么不基于与
mArray常量兼容进行测试&
?如果兼容,使用第一个,如果不兼容,使用第二个。@Yakk
is_算术
是OP中使用的测试,它也将类限制为数字数据,所以我就选择了它。哈!我喜欢删除
的第一个解决方案,因为它可以工作,而且比我想象的要简单得多!SFINAE one的好处是什么?@alle_meije在这两种情况下执行的转换是不同的(一种是将操作数转换为
T
,另一种可能不是),因此在某些情况下会有差异。谢谢,我没有想过要这样做。
+=
运算符不能接受超过1个参数,但它当然可以调用执行此操作的函数。尝试此操作后,结果表明,对于post中的代码,即使用
mDcmImage
而不是
mArray
时,然后测试返回
is_mArray
aka
std::integral_constant
,并且找不到替换?@alle ah。对不起,我需要一个衰变。添加。。。应该是固定的。
void operator+= (const T& rhs);
template <typename U> 
typename std::enable_if<std::is_arithmetic<U>::value>::type operator+= (const U& rhs);
namespace details {
  template<template<class...>class Z>
  std::false_type inherits_from_template_helper(...);
  template<template<class...>class Z, class...Us>
  std::true_type  inherits_from_template_helper(Z<Us...>&&);

}
// C++14 has this in `std`:
template<class T>using decay_t=typename std::decay<T>::type;
template<template<class...>class Z, class T>
using inherits_from_template
  = decltype(
    details::inherits_from_template_helper<Z>(
      std::declval<decay_t<T>>()
    )
  );

template<class T>
using is_mArray = inherits_from_template<mArray, T>;
template<class U>
mArray<T>& operator+=(U&& u) {
  increase_by( std::forward<U>(u), is_mArray<U>{} );
  return *this;
}
template<class U>
void increase_by( U const& u, std::false_type /* is_mArray<U> */ ) {
  // scalar addition code
}
template<class U>
void increase_by( mArray<U> const& u, std::true_type /* is_mArray<U> */ ) {
  // mArray addition code
}