C++ 派生类的重载解析失败
我使用的是mArray类,它实现了具有可变维度的数字数据容器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 ("/
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常量兼容进行测试&
?如果兼容,使用第一个,如果不兼容,使用第二个。@Yakkis_算术
是OP中使用的测试,它也将类限制为数字数据,所以我就选择了它。哈!我喜欢删除
的第一个解决方案,因为它可以工作,而且比我想象的要简单得多!SFINAE one的好处是什么?@alle_meije在这两种情况下执行的转换是不同的(一种是将操作数转换为T
,另一种可能不是),因此在某些情况下会有差异。谢谢,我没有想过要这样做。+=
运算符不能接受超过1个参数,但它当然可以调用执行此操作的函数。尝试此操作后,结果表明,对于post中的代码,即使用mDcmImage
而不是mArray
时,然后测试返回is_mArray
akastd::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
}