【发布时间】:2020-12-04 19:15:38
【问题描述】:
我正在使用CRTP 进行运算符重载。我有 基础结构。
template<int S, typename T, typename C>
struct ColorModel {
constexpr static int SPACE = S;
ColorModel() {
std::fill(begin(), end(), 0);
}
ColorModel(const ColorModel& another) {
std::copy(another.begin(), another.end(), begin());
}
ColorModel(ColorModel&& another) noexcept {
std::move(another.begin(), another.end(), begin());
}
ColorModel(const std::initializer_list<T>& l) {
std::copy(l.begin(), l.end(), begin());
}
explicit ColorModel(const T& elem) {
std::fill(begin(), end(), elem);
}
constexpr inline const T* cbegin() const {
return static_cast<const C*>(this)->components.cbegin();
}
constexpr inline const T* cend() const {
return static_cast<const C*>(this)->components.cend();
}
constexpr inline const T* begin() const {
return cbegin();
}
constexpr inline const T* end() const {
return cend();
}
constexpr inline T* begin() {
return static_cast<C*>(this)->components.begin();
}
constexpr inline T* end() {
return static_cast<C*>(this)->components.end();
}
constexpr inline size_t size() const {
return std::distance(begin(), end());
}
constexpr inline ColorModel& operator=(const ColorModel& rhs) {
std::copy(rhs.begin(), rhs.end(), begin());
return *this;
}
constexpr inline ColorModel& operator=(ColorModel&& rhs) noexcept {
std::move(rhs.begin(), rhs.end(), begin());
return *this;
}
constexpr inline ColorModel& operator=(const T& rhs) {
std::fill(begin(), end(), rhs);
return *this;
}
constexpr inline ColorModel& operator=(T&& rhs) {
std::fill(begin(), end(), rhs);
return *this;
}
constexpr inline ColorModel& operator+=(const ColorModel& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::plus<>());
return *this;
}
constexpr inline ColorModel& operator+=(ColorModel&& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::plus<>());
return *this;
}
constexpr inline ColorModel& operator+=(const T& rhs) {
util::transform(begin(), end(), rhs, begin(), std::plus<>());
return *this;
}
constexpr inline ColorModel& operator+=(T&& rhs) {
util::transform(begin(), end(), rhs, begin(), std::plus<>());
return *this;
}
constexpr inline ColorModel& operator-=(const ColorModel& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::minus<>());
return *this;
}
constexpr inline ColorModel& operator-=(ColorModel&& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::minus<>());
return *this;
}
constexpr inline ColorModel& operator-=(const T& rhs) {
util::transform(begin(), end(), rhs, begin(), std::minus<>());
return *this;
}
constexpr inline ColorModel& operator-=(T&& rhs) {
util::transform(begin(), end(), rhs, begin(), std::minus<>());
return *this;
}
constexpr inline ColorModel& operator*=(const ColorModel& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::multiplies<>());
return *this;
}
constexpr inline ColorModel& operator*=(ColorModel&& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::multiplies<>());
return *this;
}
constexpr inline ColorModel& operator*=(const T& rhs) {
util::transform(begin(), end(), rhs, begin(), std::multiplies<>());
return *this;
}
constexpr inline ColorModel& operator*=(T&& rhs) {
util::transform(begin(), end(), rhs, begin(), std::multiplies<>());
return *this;
}
constexpr inline ColorModel& operator/=(const ColorModel& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::divides<>());
return *this;
}
constexpr inline ColorModel& operator/=(ColorModel&& rhs) {
std::transform(begin(), end(), rhs.begin(), begin(), std::divides<>());
return *this;
}
constexpr inline ColorModel& operator/=(const T& rhs) {
util::transform(begin(), end(), rhs, begin(), std::divides<>());
return *this;
}
constexpr inline ColorModel& operator/=(T&& rhs) {
util::transform(begin(), end(), rhs, begin(), std::divides<>());
return *this;
}
constexpr inline ColorModel operator+(const ColorModel& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::plus<>());
return result;
}
constexpr inline ColorModel operator+(ColorModel&& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::plus<>());
return result;
}
constexpr inline ColorModel operator+(const T& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::plus<>());
return result;
}
constexpr inline ColorModel operator+(T&& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::plus<>());
return result;
}
constexpr inline ColorModel operator-(const ColorModel& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::minus<>());
return result;
}
constexpr inline ColorModel operator-(ColorModel&& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::minus<>());
return result;
}
constexpr inline ColorModel operator-(const T& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::minus<>());
return result;
}
constexpr inline ColorModel operator-(T&& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::minus<>());
return result;
}
constexpr inline ColorModel operator*(const ColorModel& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::multiplies<>());
return result;
}
constexpr inline ColorModel operator*(ColorModel&& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::multiplies<>());
return result;
}
constexpr inline ColorModel operator*(const T& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::multiplies<>());
return result;
}
constexpr inline ColorModel operator*(T&& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::multiplies<>());
return result;
}
constexpr inline ColorModel operator/(const ColorModel& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::divides<>());
return result;
}
constexpr inline ColorModel operator/(ColorModel&& rhs) const {
ColorModel result;
std::transform(begin(), end(), rhs.begin(), result.begin(), std::divides<>());
return result;
}
constexpr inline ColorModel operator/(const T& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::divides<>());
return result;
}
constexpr inline ColorModel operator/(T&& rhs) const {
ColorModel result;
util::transform(begin(), end(), rhs, result.begin(), std::divides<>());
return result;
}
};
template<int S, typename T, typename C>
std::ostream& operator<<(std::ostream& os, const ColorModel<S, T, C>& model) {
for (const auto& elem : model) {
os << elem << " ";
}
return os;
}
这是基础结构的子
struct RGB : ColorModel<0, int, RGB> {
std::array<int, 3> components;
RGB() : ColorModel() {
}
RGB(const RGB& other) : ColorModel(other) {
}
RGB(RGB&& other) : ColorModel(other) {
}
RGB(const std::initializer_list<int>& l) : ColorModel(l) {
}
explicit RGB(const int& elem) : ColorModel(elem) {
}
using ColorModel<0, int, RGB>::operator=;
};
这是我的util::transform函数的代码
namespace util {
template<typename Iterator, typename T, typename BinaryOperator>
void transform(Iterator begin, Iterator end, const T& elem, Iterator result, BinaryOperator anOperator) {
for (; begin != end; ++begin, ++result) {
*result = anOperator(*begin, elem);
}
}
}
但是当我开始在 main.cpp 中测试它时,我得到了奇怪的结果。
int main() {
RGB rgb1{1, 2, 3};
RGB rgb2{2, 3, 4};
RGB rgb3(10);
rgb3 += rgb3 + rgb1+rgb2;
std::cout << rgb3 << std::endl << rgb1 << std::endl << rgb2;
}
我得到10 15 20 而不是13 15 17,我一直试图找出原因。
提前谢谢。
附:对不起所有 constexpr inline 我只是在本地测试一些东西。
【问题讨论】:
-
@NathanOliver 是的,我忘了更新复制粘贴的部分,谢谢)
-
您应该真正测试您提供给我们的 MCVE,以确保问题仍然可以重现。
-
什么是
util?你有自己的功能吗? -
对不起,这是我的功能,与问题无关,我已经更新并删除了它。
标签: c++ operator-overloading parentheses crtp