I get an error as
FastOut<NMAX>::Flags FastOut<NMAX>::operator&(FastOut<NMAX>::Flags, FastOut<NMAX>::Flags) must take either zero or one argument
template<int NMAX>
class FastOut{
enum class Flags;
protected:
char buffer[NMAX];
std::map<Flags,bool>FM={(UP,0),(LOW,0),(BOOL,0)};
public:
enum class Flags{upper,lower,boolapha };
friend Flags operator&(Flags a,Flags b);
FastOut();
FastOut(const char *);
FastOut(const std::string&);
FastOut & operator << (int);
FastOut & operator << (char);
FastOut & operator << (long long);
FastOut & operator << (float);
FastOut & operator << (double);
FastOut & operator << (char *);
FastOut & operator << (const std::string &);
FastOut & operator << (const FastOut&);
void open(const char*);
void open(const std::string&);
void flush();
void clear();
~FastOut();
};
template<int NMAX>
typename FastOut<NMAX>::Flags FastOut<NMAX>::operator&(Flags a,Flags b){
}
I want to be able to say FasOut<N>::Flags a= FastOut<N>::Flags::upper | FastOut<N>::Flags::lower
A binary operator member should only take one parameter, the right-hand argument – the left-hand argument is *this.
template<int NMAX>
typename FastOut<NMAX>::Flags FastOut<NMAX>::operator&(Flags rhs) const
{
// Return *this & rhs
}
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 am implementing an iterator for a Queue data type, but the iterator is being initialized as a const inside of the class implementation for some reason. I cannot figure out why the constructor is causing the iterator to return itself as a const.
Any feedback as to what the intricasies of the C++ language that may be causing my problem could be, would be very helpful.
The Error I am receiving from Eclipse which seems to be coming from my begin() method is:
../src/linked_queue.hpp:315:35: error: invalid conversion from
'const ics::LinkedQueue<int>*' to 'ics::LinkedQueue<int>*' [-fpermissive]
Interface:
#ifndef LINKED_QUEUE_HPP_
#define LINKED_QUEUE_HPP_
#include <string>
#include <iostream>
#include <sstream>
#include <initializer_list>
#include "ics_exceptions.hpp"
namespace ics {
template<class T> class LinkedQueue {
public:
//Destructor/Constructors
~LinkedQueue();
LinkedQueue ();
LinkedQueue (const LinkedQueue<T>& to_copy);
explicit LinkedQueue (const std::initializer_list<T>& il);
template <class Iterable>
explicit LinkedQueue (const Iterable& i);
//Queries
bool empty () const;
int size () const;
T& peek () const;
std::string str () const; //supplies useful debugging information; contrast to operator <<
//Commands
int enqueue (const T& element);
T dequeue ();
void clear ();
template <class Iterable>
int enqueue_all (const Iterable& i);
//Operators
LinkedQueue<T>& operator = (const LinkedQueue<T>& rhs);
bool operator == (const LinkedQueue<T>& rhs) const;
bool operator != (const LinkedQueue<T>& rhs) const;
template<class T2>
friend std::ostream& operator << (std::ostream& outs, const LinkedQueue<T2>& q);
private:
class LN;
public:
class Iterator {
public:
~Iterator();
T erase();
std::string str () const;
LinkedQueue<T>::Iterator& operator ++ ();
LinkedQueue<T>::Iterator operator ++ (int);
bool operator == (const LinkedQueue<T>::Iterator& rhs) const;
bool operator != (const LinkedQueue<T>::Iterator& rhs) const;
T& operator * () const;
T* operator -> () const;
friend std::ostream& operator << (std::ostream& outs, const LinkedQueue<T>::Iterator& i) {
outs << i.str();
return outs;
}
friend Iterator LinkedQueue<T>::begin () const;
friend Iterator LinkedQueue<T>::end () const;
private:
LN* prev = nullptr;
LN* current;
LinkedQueue<T>* ref_queue;
int expected_mod_count;
bool can_erase = true;
Iterator(LinkedQueue<T>* iterate_over, LN* initial);
};
Iterator begin () const;
Iterator end () const;
private:
class LN {
public:
LN () {}
LN (const LN& ln) : value(ln.value), next(ln.next){}
LN (T v, LN* n = nullptr) : value(v), next(n){}
T value;
LN* next = nullptr;
};
LN* front = nullptr;
LN* rear = nullptr;
int used = 0; //Cache for number of values in linked list
int mod_count = 0; //For sensing any concurrent modifications
//Helper methods
void delete_list(LN*& front);
};
Implementation (I've included only a section of my Iterator code):
template<class T>
auto LinkedQueue<T>::begin () const -> LinkedQueue<T>::Iterator {
return Iterator(this, this->front);
}
template<class T>
auto LinkedQueue<T>::end () const -> LinkedQueue<T>::Iterator {
// return Iterator(this, this->rear);
}
template<class T>
LinkedQueue<T>::Iterator::Iterator(LinkedQueue<T>* iterate_over, LN* initial) {
ref_queue = iterate_over;
expected_mod_count = iterate_over->mod_count;
current = initial;
}
The error is because Iterator begin () const; is marked as const, hence the this used in the function is const as well. So in turn, the compiler gives the error that it cannot convert from a const to non-const.
Given that the function signatures are fixed in this case, to resolve the error, added const will help solve the issue.
You could add const to the constructor signature
Iterator(LinkedQueue<T> const* iterate_over, LN* initial);
And make the member const as well
LinkedQueue<T> const* ref_queue;
Adding the const where required to ensure that members and functions remain const as required is known as being const correct.
I'm learning C++ and I've been writing a wrapper for std::map and std::string, and I've stumbled upon a problem. Whenever I add something to the map using a string as key, once I try to access that item using the exact same key it says the key is out of bounds of the map. Here's my code (irrelevant parts left out):
ADictionary.h
#ifndef ADICTIONARY_H
#define ADICTIONARY_H
#include <map>
...
template<typename KEY, typename VALUE>
class ADictionary {
public:
...
VALUE operator [](KEY key) const {
return value.at(key);
}
void add(KEY key, VALUE value) {
this->value.insert(std::make_pair(key, value));
}
...
private:
std::map<KEY, VALUE> value;
};
#endif
AString.cpp
#include "AString.h"
AString::AString() {
value = "";
}
AString::AString(const char character) {
value = character;
}
AString::AString(const char * characters) {
value = characters;
}
AString::AString(std::string text) {
value = text;
}
...
AString::operator const char *() const {
return value.c_str();
}
AString::operator const std::string() const {
return value;
}
...
ABoolean AString::operator<(AString & text) const {
return getLength() < text.getLength();
}
ABoolean AString::operator>(AString & text) const {
return text < *this;
}
ABoolean AString::operator==(AString & text) const {
return value == text.value;
}
ABoolean AString::operator!=(AString & text) const {
return !(text == *this);
}
AString & AString::operator=(AString & text) {
value = text.value;
return *this;
}
...
The code which uses the above
ADictionary<AString, AString> test;
AString a = "a";
AString b = "b";
test.add(a, b);
std::cout << test[a]; // Error occurs here, according to the program "a" is not a key in the map
I hope someone can explain to me what's going wrong. I've tried creating a dictionary with the default std::string as types and it worked correctly:
ADictionary<std::string, std::string> test;
std::string a = "a";
std::string b = "b";
test.add(a, b);
std::cout << test[a]; // No error this time
As I've said, I'm pretty new to C++ so there may be other errors. If so, feel free to point them out.
Thanks!
EDIT:
AString.h
#ifndef ASTRING_H
#define ASTRING_H
#include <string>
#include "ABoolean.h"
#include "AInteger.h"
#include "AList.h"
class ABoolean;
class AInteger;
template<typename VALUE>
class AList;
class AString {
public:
AString();
AString(const char);
AString(const char *);
AString(std::string);
~AString();
operator const char *() const;
operator const std::string() const;
operator const AInteger() const;
ABoolean operator<(AString &) const;
ABoolean operator>(AString &) const;
ABoolean operator==(AString &) const;
ABoolean operator!=(AString &) const;
AString & operator=(AString &);
AString & operator+(AString &);
AString & operator+=(AString &);
void clear();
ABoolean contains(AString) const;
AInteger getIndex(AString) const;
AInteger getLength() const;
AList<AString> getSplit(AString) const;
AString getSubstring(AInteger, AInteger) const;
void removeRange(AInteger, AInteger);
void removeSubstring(AString);
void toLowercase();
void toUppercase();
private:
std::string value;
};
AString & operator+(const char, AString &);
AString & operator+(const char *, AString &);
#endif
Your string operators appear to be incorrect.
std::map uses the less than operator by default. While you provide one for AString, the only thing it does is check the length of the string. What if the two strings are of equal length?
The correct thing to do is to lexicographically compare the characters in the string. While there is a standard library function to do this, you can use operator < of the std::string values in your class:
friend bool operator<(AString const& a, AString const& b)
{
return a.value < b.value;
}
EDIT: You may also wish to remove your conversion operators, or at least make them explicit, which prevents surprising and unwanted implicit conversions. Constructors taking one parameter (other than copy or move constructors) should also be declared explicit.
I have the following class:
class MyInteger
{
private:
__int64 numero;
static __int64 int64Pow(__int64, __int64);
public:
// It doesn't matter how these methods are implemented
friend class MyInteger;
MyInteger(void);
MyInteger(const MyInteger&);
MyInteger(const __int64&);
~MyInteger(void);
static MyInteger const minValue;
static MyInteger const maxValue;
MyInteger& operator = (const MyInteger&);
MyInteger operator + (const MyInteger&) const;
MyInteger operator - (const MyInteger&) const;
MyInteger operator * (const MyInteger&) const;
MyInteger operator / (const MyInteger&) const;
MyInteger& operator += (const MyInteger&);
MyInteger& operator -= (const MyInteger&);
MyInteger& operator *= (const MyInteger&);
MyInteger& operator /= (const MyInteger&);
MyInteger operator % (const MyInteger&) const;
MyInteger& operator %= (const MyInteger&);
MyInteger& operator ++ ();
MyInteger operator ++ (int);
MyInteger& operator -- ();
MyInteger operator -- (int);
bool operator == (const MyInteger&) const;
bool operator != (const MyInteger&) const;
bool operator > (const MyInteger&) const;
bool operator < (const MyInteger&) const;
bool operator >= (const MyInteger&) const;
bool operator <= (const MyInteger&) const;
int toStdInt() const
{
return (int)numero;
}
float toStdFloat() const;
double toStdDouble() const;
char toStdChar() const;
short toStdShortInt() const;
long toStdLong() const;
long long toStdLongLong() const;
unsigned int toStdUInt() const;
__int64 toStdInt64() const;
unsigned __int64 toStdUInt64() const;
unsigned long long int toStdULongLong() const;
long double toStdULongDouble() const;
template<class Type>
Type& operator[](Type* sz)
{
return sz[toStdULongLong()];
}
};
template<class Type>
Type* operator+(const Type* o1, const MyInteger& o2)
{
return ((o1) + (o2.toStdInt()));
}
I'd like to use this class to access array elements like this:
MyInteger myInt(1);
int* intPtr = (int*)malloc(sizeof(int) * N);
intPtr[myInt] = 1;
I thought that the function
template<class Type>
Type* operator+(const Type* o1, const MyInteger& o2)
{
return ((o1) + (o2.toStdInt()));
}
could solve my problem, because as this post reports (Type of array index in C++) "The expression E1[E2] is identical (by definition) to *((E1)+(E2))", but I get the C2677 error ('[' operator: no global operator found which takes type 'MyInteger' (or there is no acceptable conversion))
Can someone clarify me this situation?
Thanks
You may be able to do that by overriding the cast to int of your MyInteger class in a way similar to:
class MyInteger {
...
operator int() const
{
return toStdInt(); /** Your class as an array index (int) */
}
...
}