is it possible to overload the operator% for two doubles?
const double operator%(const double& lhs, const double& rhs)
{
return fmod(lhs, rhs);
}
Of course, this generates an error because one of the two parameters must have a class type.
So I thought about utilizing the possibility of implicit constructor calls of C++ to get around of this problem. I did it in the following way:
class MyDouble {
public:
MyDouble(double val) : val_(val) {}
~MyDouble() {}
double val() const { return val_; }
private:
double val_;
};
const double operator%(const MyDouble& lhs, const double& rhs)
{
return fmod(lhs.val(), rhs);
}
const double operator%(const double& lhs, const MyDouble& rhs)
{
return fmod(lhs, rhs.val());
}
... and:
double a = 15.3;
double b = 6.7;
double res = a % b; // hopefully calling operator%(const MyDouble&, const double) using a implicit constructor call
Unfortunately, this does not work! Any hints, ideas, ... are appreciated!
Thanks in advance,
Jonas
The reason this doesn't work is because overload resolution for user defined operator functions is only triggered if at least one operand of the expression has a class or enumeration type.
So you are out of luck. This won't work.
I think the best you could try is waiting for a C++0x compiler and instead of writing 3.14, you write 3.14_myd, as a user defined literal.
alternatively, implement double MyDouble::operator%(const double&) const;, like so:
#include <iostream>
#include <cmath>
class t_double {
public:
t_double(const double& val) : d_val(val) {
}
t_double(const t_double& other) : d_val(other.d_val) {
}
~t_double() {
}
const double& val() const {
return this->d_val;
}
double operator%(const double& rhs) const {
return fmod(this->val(), rhs);
}
double operator%(const t_double& rhs) const {
return fmod(this->val(), rhs.val());
}
private:
double d_val;
};
int main(int argc, char* const argv[]) {
const t_double a(15.3);
const t_double b(6.7);
std::cout << a % b << " == " << a.val() << " % " << b.val() << "\n";
return 0;
}
Related
How do i fix this?
I'm getting error: 'this' argument has type const but function is not marked const c++ overload operator
template <class T>
class Rational {
private:
T n = 0;
T d = 1;
public:
Rational() = default;
T numerator() {
return n;
}
T denominator() {
return d;
}
};
template <class T>
inline bool const operator ==(const Rational <T> & lhs, const Rational <T>& rhs) {
return lhs.numerator() * rhs.denominator() == lhs.denominator() * rhs.numerator();
}
My guess is that numerator() and denominator() member functions are not const member functions. Make them const. After that, the above function should work.
BTW, there is no need for the return type to be bool const. Keep it simple and change it to bool.
If numerator() and denominator() are to be used to directly assign to Rationals internal member variables as well as being used in const contexts, you need two sets of overloads. One mutable and one const:
// mutable interface
T& Rational::numerator();
T& Rational::denominator();
// const interface if T may only be a fundamental integral type
T Rational::numerator() const;
T Rational::denominator() const;
// const interface if sizeof(T) may be > sizeof(T*)
T const& Rational::numerator() const;
T const& Rational::denominator() const;
Note, only one of the const interfaces may be used so you need to select one of them.
Here's an example of how it can be done:
#include <iostream>
#include <type_traits>
template<typename T>
class Rational {
public:
// pass by value for fundamental types, by const& for other types
using by_value_or_by_const_ref =
std::conditional_t<std::is_fundamental_v<T>, T, T const&>;
Rational(by_value_or_by_const_ref n, by_value_or_by_const_ref d) :
m_numerator(n), m_denominator(d) {}
// mutable interface
T& numerator() { return m_numerator; }
T& denominator() { return m_denominator; }
// const interface
by_value_or_by_const_ref numerator() const { return m_numerator; }
by_value_or_by_const_ref denominator() const { return m_denominator; }
private:
T m_numerator;
T m_denominator;
};
template<class T>
inline bool operator==(const Rational<T>& lhs, const Rational<T>& rhs) {
// using const interface
return lhs.numerator() * rhs.denominator() ==
lhs.denominator() * rhs.numerator();
}
int main() {
Rational<int> a(10, 20);
Rational<int> b(10, 10);
// using mutable interface
a.denominator() /= 4;
b.numerator() *= 2;
std::cout << std::boolalpha << (a == b) << "\n";
}
Similar to this problem posted here. I Need to create three classes:
"Number" class supports three operations,such as, “display”, “==”,
and “+”;
"Integer class" that represented by integer;
"Fraction" class is represented by numerator and denominator.
Requirements:
It should support the operations: (a) Integer (I) + Fraction (F),
(b) F+I, (c) F+F, (d) I+I, and comparing them
The caller of the + operation doesn't need to know the return type.
I could solve the problem till requirement# 1. However, couldn't figure out the second requirement yet. Any help would be appreciated.
To keep it brief, I am going to share the header file of my code below, function definition of the code can be shared if needed.
Number.h
#pragma once
template<class T>
class Number
{
public:
bool operator== (const T&)
{
return impl().operator == ();
}
T operator+ (const T &) const
{
return impl().operator+();
}
template <typename Stream>
void display(Stream& os) const
{
impl().display(os);
}
private:
T& impl() {
return *static_cast<T*>(this);
}
T const & impl() const {
return *static_cast<T const *>(this);
}
};
Integer.h
#pragma once
#include "Number.h"
class Integer : public Number<Integer>
{
int intValue{0};
public:
template <typename Stream>
void display(Stream& os) const
{
os << this->intValue << '\n';
}
Integer() = default;
~Integer() = default;
Integer(int num);
int getIntValue() const;
bool operator== (const Integer &);
Integer operator+ (const Integer &) const;
};
Fraction.h
#pragma once
#include <math.h>
#include "Number.h"
#include "Integer.h"
#include <iostream>
class Fraction : public Number<Fraction>
{
int _numerator{0};
int _denominator{1};
int gcdCalculate(int val1, int val2) const;
int lcmCalculate(const int val1, const int val2) const;
public:
template <typename Stream>
void display(Stream& os) const
{int tempNum = this->_numerator;
int tempDen = this->_denominator;
double tempFrac = (double)tempNum/(double)tempDen;
double intpart;
if (this->_denominator==0)
{
std::cout << "Undefined " << this->_numerator << "/" << this->_denominator << "(Divide by zero exception)";
}
else if (this->_denominator==1){
std::cout << this->_numerator << std::endl;
}
else {
os << this->_numerator << "/";
os << this->_denominator << '\n';}
}
Fraction() = default;
Fraction(int num, int den);
~Fraction() = default;
bool operator== (const Fraction &);
bool operator== (const Integer &);
friend bool operator== (const Integer&, const Fraction&);
Fraction operator+ (const Fraction &) const;
Fraction operator+ (const Integer &) const;
friend Fraction operator+ (const Integer&, const Fraction&);
};
main.cpp
#include <iostream>
using namespace std;
template <typename INumberType>
void GenericDisplay(const Number<INumberType>& num) //Here we are calling through the Number<> Interface
{
num.display(cout);
}
int main()
{
Fraction fracOne(1,4);
Fraction fracTwo(2,8);
Integer intOne(30);
Integer intTwo(30);
Fraction sumOfFractionOneTwo = fracOne + fracTwo;
Integer sumOfIntegerOneTwo = intOne + intTwo;
Fraction sumOfFractionOneAndIntegerOne = integerOne + fracOne;
Fraction sumOfFractionTwoAndIntegerTwo = fracTwo + intTwo;
return 0;
}
In this code, caller of the + operator knows the return type, e.g., in the int main() caller defined returned type "Fraction sumOfFractionOneAndIntegerOne = integerOne + fracOne;". Which is incorrect!
The way I want, caller should not know the return type. e.g., "Number sumOfFractionOneAndIntegerOne = integerOne + fracOne;"
Again, any help would be appreciated.
Since the type is statically known, the caller can use auto for the type of the variable, so that the type is deduced instead of explicitly specified. Otherwise, you may be looking for virtual inheritance, which allows an abstract base to be used as the type while derived classes provide implementation for further operators.
I'm writing my own typesafe enum header-only library at https://bitbucket.org/chopsii/typesafe-enums
The idea is to replace the non-type-safe c-style enum like:
enum ItemCategory
{
BLOCK,
WEAPON
};
with something that's properly type safe.
So far, my solution uses a macro that, for an example equivalent to the above enum, looks like this:
TypesafeEnum(ItemCategory,
(BLOCK)
(WEAPON)
);
And expands to something that looks like this:
template<typename InnerType>
class Wrapped {
public:
InnerType getValue() const { return _val; }
bool operator<(const Wrapped<InnerType>& rhs) const { ; return _val < rhs._val; }
bool operator>(const Wrapped<InnerType>& rhs) const { ; return _val > rhs._val; }
bool operator==(const Wrapped<InnerType>& rhs) const { ; return _val == rhs._val; }
private:
InnerType _val;
protected:
explicit Wrapped<InnerType>(const InnerType& val) : _val(val) {}
void setValue(const InnerType& val) { _val = val; }
};
class WrappedTypeItemCategory : private Wrapped<int>
{
private:
typedef const std::string* strptr;
typedef const std::string* const cstrptr;
explicit WrappedTypeItemCategory(const std::string& label, int val): Wrapped<int>(val), str(&label)
{}
cstrptr str;
public:
static WrappedTypeItemCategory make(const std::string& label, int val)
{
return WrappedTypeItemCategory(label, val);
}
void operator=(const WrappedTypeItemCategory& rhs)
{
;
setValue(rhs.getValue());
const_cast<strptr>(str) = rhs.str;
}
int getValue() const
{
return Wrapped<int>::getValue();
}
const std::string& getString() const
{
return *str;
}
bool operator<(const WrappedTypeItemCategory & rhs) const
{
;
return getValue() < rhs.getValue();
}
bool operator>(const WrappedTypeItemCategory & rhs) const
{
;
return getValue() > rhs.getValue();
}
bool operator==(const WrappedTypeItemCategory & rhs) const
{
;
return getValue() == rhs.getValue();
}
friend std::ostream & operator<<(std::ostream &os, const WrappedTypeItemCategory& rhs)
{
;
return os << *rhs.str << "(" << rhs.getValue() << ")";
}
};
;
namespace {
template<typename T> class ItemCategoryInner : public TypesafeEnumBase
{
public:
static const WrappedTypeItemCategory BLOCK;
static const WrappedTypeItemCategory WEAPON;
static const std::string BLOCKStr;
static const std::string WEAPONStr;
};
template<typename T> const WrappedTypeItemCategory ItemCategoryInner<T>::BLOCK = WrappedTypeItemCategory::make(ItemCategoryInner<T>::BLOCKStr, 0);
template<typename T> const WrappedTypeItemCategory ItemCategoryInner<T>::WEAPON = WrappedTypeItemCategory::make(ItemCategoryInner<T>::WEAPONStr, 1);
template<typename T> const std::string ItemCategoryInner<T>::BLOCKStr("ItemCategory::BLOCK");
template<typename T> const std::string ItemCategoryInner<T>::WEAPONStr("ItemCategory::WEAPON");
struct ItemCategoryTemplateConstantTrick
{};
};
class ItemCategory : public ItemCategoryInner<ItemCategoryTemplateConstantTrick>
{
private:
const WrappedTypeItemCategory* const val;
public:
class InvalidValueError : public std::runtime_error
{
public:
const int val;
InvalidValueError(int val): std::runtime_error(std::string("Invalid value given for ") + "ItemCategory::make"), val(val)
{}
};
ItemCategory(const WrappedTypeItemCategory& value): val(&value)
{}
void operator=(const ItemCategory& rhs)
{
const_cast<const WrappedTypeItemCategory*>(val) = rhs.val;
}
static ItemCategory make(const int& val)
{
if (val == ItemCategory::BLOCK.getValue()) return ItemCategory(ItemCategory::BLOCK);
if (val == ItemCategory::WEAPON.getValue()) return ItemCategory(ItemCategory::WEAPON);
;
throw InvalidValueError(val);
}
const WrappedTypeItemCategory* const getWrappedValue() const
{
return val;
}
int getValue() const
{
return val->getValue();
}
const std::string & getString() const
{
return val->getString();
}
bool operator<(const ItemCategory& rhs) const
{
return *val < *rhs.val;
}
bool operator>(const ItemCategory& rhs) const
{
return *val > *rhs.val;
}
bool operator==(const WrappedTypeItemCategory& rhs) const
{
return *val == rhs;
}
bool operator!=(const WrappedTypeItemCategory& rhs) const
{
return !(*val == rhs);
}
bool operator<=(const WrappedTypeItemCategory& rhs) const
{
return (*val == rhs || *val < rhs);
}
bool operator>=(const WrappedTypeItemCategory& rhs) const
{
return (*val == rhs || *val > rhs);
}
void print(std::ostream& os) const override
{
os << *val;
}
friend std::ostream & operator<<(std::ostream &os, const ItemCategory& rhs)
{
rhs.print(os);
return os;
}
};
;
If I manually pre-expand it, like I have done here - by pre-compiling to file - then intellisense handles it all up until the line that says:
class ItemCategory : public ItemCategoryInner<ItemCategoryTemplateConstantTrick>
At which point it starts thinking ItemCategoryInner and ItemCategoryTemplateConstantTrick are ambiguous, along with many other things on every few lines of the file.
The header that contains this code is included in many places. I know I'm violating the One Definition Rule, which is why I'm using the Template Constant Trick, but I think I need to violate the ODR as my goal is to have an easy to use Macro based typesafe replacement for C++ enums.
I'm not sure if it's the violation of ODR that is the cause of my issues, or something else. I tried __declspec(selectany) but it didn't seem to help - and I would prefer if this macro would be eventually cross-platform, because if it works out, I have other projects I would use it in.
Either way, the .cpp files etc that make use of the enum are able to, and intellisense correctly suggests the options.
However, on a possibly related note, if I don't pre-expand the macro, intellisense isn't able to parse it and it doesn't know what a ItemCategory is at all, even though it compiles and works fine.
I just want my intellisense to work properly with my typesafe enums - it slows down intellisense and confuses it in other code in the same project.
as you can see from the code I want to overload the < operator twice. 1 to sort by dist and the other by nodeID. I would like to check if there is any way to call the different overloaded methods. For example in the compLoc method, when I use the sort() method I want it to be sorted by nodeID but in other methods I want it to be sorted by dist.
struct AttSet{
int nodeID;
double dist;
bool operator < (const AttSet & str) const{
return (dist < str.dist);
}
/*
bool operator <(const AttSet & str){
return (nodeID < str.nodeID);
*/
bool operator == (const AttSet & str){
return nodeID == str.nodeID;
}};
void compLoc(Edge *edge, vector<Node*> &vertices){
int l = edge->length;
int vl = edge->head->nodeID;
int vr = edge->tail->nodeID;
/*
sort(vertices[vl]->attSet.begin(), vertices[vl]->attSet.end());
sort(vertices[vr]->attSet.begin(), vertices[vr]->attSet.end());
vector<AttSet> vInterSec;
set_intersection(vertices[vl]->attSet.begin(), vertices[vl]->attSet.end(), vertices[vr]->attSet.begin(), vertices[vr]->attSet.end(), back_inserter(vInterSec));
*/}
You cannot have overloads that have the same signature. This holds for any function. How would you try to decide which version to use?
If you want sort the object based on different criteria you should use the sort version that takes a custom comparer function as the third argument.
Edit:
Of course you need to provide the comparer. I would suggest providing the comparers as static functions of the class if you have such power. This way you will not pollute enclosing namespace and you can access privates of the class with out exposing any getters. Since your properties are public the lambda would suffice, and probably be the best/cleanest approach.
Feeling adventurous I made a simple c++11 exercise program. For what it's worth, if you ever decided to go for proper encapsulation, I've shown both approaches:
#include <iostream>
#include <algorithm>
#include <vector>
#include <initializer_list>
#include <cassert>
using namespace std;
template<typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& v){
for(const auto& el : v){
out << el << '\n';
}
return out;
}
class A {
int a;
int b;
public:
A(std::initializer_list<int> l){
assert(l.size() == 2);
auto i = l.begin();
a = *i;
++i;
b = *i;
}
friend std::ostream& operator<<(std::ostream& stream, const A& e){
return stream << e.a << ' ' << e.b;
}
static bool compareViaA(const A& lhs, const A& rhs){
return rhs.a > lhs.a;
}
static bool compareViaB(const A& lhs, const A& rhs){
return rhs.b > lhs.b;
}
};
int main() {
std::vector<A> v {{2,3}, {3,2}, {1,4}, {4,1}};
//sort(v.begin(), v.end(), [](const A& a, const A& b){return a.a > b.a;}) // fails because of privacy violation
sort(v.begin(), v.end(), A::compareViaA);
std::cout << v << '\n';
sort(v.begin(), v.end(), A::compareViaB);
std::cout << v << '\n';
return 0;
}
Live: http://ideone.com/lDMujx.
I think you can implement this by using functor and take the comparator(operator< overload) outside the AttSet.
Here is a simple example:
struct AtrComparator {
bool distcmp;
AttrComparator(bool distcmp): distcmp(distcmp) {}
bool operator() (const AttSet &s1, const AttSet &s2) {
if(distcmp) {
return s1.dist < s2.dist;
} else {
return s1.nodeID < s2.nodeID;
}
}
}
And then you can do the sort through different feed, dist or nodeID.
.e.g:
sort(vertices[vl]->attSet.begin(), vertices[vl]->attSet.end(), AttComparator(true));
sort(vertices[vl]->attSet.begin(), vertices[vl]->attSet.end(), AttComparator(false));
You can't do that. They have the same signature exactly.
Use a functor or a lambda and pass it to whatever algorithm you want.
std::sort(std::begin(container), std::end(container),
[](const element_type& lhs, const element_type& rhs) { return ...; });
Another way to do this:
struct compare_by_node_id {
bool operator()(const AttSet& lhs, const AttSet& rhs) const {
return lhs.nodeID < rhs.nodeID;
}
};
struct compare_by_dist {
bool operator()(const AttSet& lhs, const AttSet& rhs) const {
return lhs.dist < rhs.dist;
}
};
And you could pass that to the algorithm like:
std::sort(std::begin(container), std::end(container), compare_by_node_id());
you cannot do that because compiler doesn't see difference between:
bool operator < (const AttSet & str) const; //this const doesn't allow to override any property of object(instance of AttSet) if I remember
and
bool operator < (const AttSet & str);
there're the same same return type, same parameter (same signature)
compiler cannot choose which one is better
There's not a great way to do this as far as I am aware, since the compiler will see these as the exact same and will throw an error. If you need to do this, use the < operator as whatever will occur the most often, and then write a method that you can call to compare two object. Something like this:
bool operator< (const Blah &blah) const {
return (most often operation)
}
bool Blah::other_operation(const Blah &blah) const {
return (other operation)
}
im new to C++, although i do know the general C syntax. I've been trying to create a class with operator overloading. But i can't get it to work. Well partially got it to work.
Working operator overloading in same source:
//test.cpp
#include <iostream>
class Fraction
{
int gcd(int a, int b) {return b==0 ? a : gcd(b,a%b); }
int n, d;
public:
Fraction(int n, int d = 1) : n(n/gcd(n,d)), d(d/gcd(n,d)) {}
int num() const { return n; }
int den() const { return d; }
Fraction& operator*=(const Fraction& rhs) {
int new_n = n*rhs.n / gcd(n*rhs.n, d*rhs.d);
d = d*rhs.d / gcd(n*rhs.n, d*rhs.d);
n = new_n;
return *this;
}
};
std::ostream& operator<<(std::ostream& out, const Fraction& f){
return out << f.num() << '/' << f.den() ;
}
bool operator==(const Fraction& lhs, const Fraction& rhs) {
return lhs.num() == rhs.num() && lhs.den() == rhs.den();
}
bool operator!=(const Fraction& lhs, const Fraction& rhs) {
return !(lhs == rhs);
}
Fraction operator*(Fraction lhs, const Fraction& rhs)
{
return lhs *= rhs;
}
int main()
{
Fraction f1(3,8), f2(1,2), f3(10,2);
std::cout << f1 << '*' << f2 << '=' << f1*f2 << '\n'
<< f2 << '*' << f3 << '=' << f2*f3 << '\n'
<< 2 << '*' << f1 << '=' << 2 *f1 << '\n';
}
Output:
3/8*1/2=3/16
1/2*5/1=5/2
2*3/8=3/4
Source: http://en.cppreference.com/w/cpp/language/operators
Now my code, trying to apply the code from above
//vectors.h
class Vector2
{
public:
Vector2(void);
~Vector2(void);
int counter;
Vector2& operator+=(const Vector2& vec);
}
//vectors.cpp
#include "vectors.h"
Vector2::Vector2(void)
{
counter = 0;
}
Vector2::~Vector2(void)
{
}
Vector2& operator+=(Vector2& vec)//error: too few parameters
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
#include "vectors.h"
int main(void)
{
Vector2 vector();
while(true)
{
vector += vector;//error: expression must be a modifiable value
printf("Vector counter: %d\n",vector.counter);
}
}
What i'm trying to do:
I'm trying to make my own class, and use operator overloading. But the part i can't get to work is defining the class with a header while keeping operator overloading working.
Thanks for reading my question
The following compiled in ideone: http://ideone.com/ratVVT
Changes are:
Implementation of (overload) method must specify the Class name
Implementation of (overload) method must have the same signature as the declaration (missing const).
Declaring the variable vector in main Vector2 vector(); was interpreted as a function declaration, instead of a Vector2 variable.... use Vector2 vector; or Vector2 vector=Vector2()
The code copied below.
#include <iostream>
//vectors.h
class Vector2
{
public:
Vector2();
~Vector2();
int counter;
Vector2& operator+=(const Vector2& vec);
};
//vectors.cpp
//#include "vectors.h"
Vector2::Vector2()
{
counter = 0;
}
Vector2::~Vector2()
{
}
Vector2& Vector2::operator+=(const Vector2& vec)// <---- CHANGE
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
//#include "vectors.h"
int main()
{
Vector2 vector; // <---- CHANGE
while(true)
{
vector += vector;
printf("Vector counter: %d\n",vector.counter);
}
}
You are missing the class name in your method definition Vector2:: and the signature does not match because of the first parameter missing a const.
Vector2& Vector2::operator+=(const Vector2& vec)