I am writing a CheckedPtr class to practice exception handling (Stroustrup, TC++PL Exercises, 4th Ed., problem 14.1). I want to overload a bunch of operators, and the code to do this is almost the same. I am using macros to avoid being too repetitive, but I know macros are dangerous, so I was wondering if a better method exists.
Here is my code -- the portion shown is part of what I defined within a class called CheckedPtr. Can I do it better, and/or without macros? I would rather not write all of these functions manually, even if it means some risk with macros.
// This is relatively dangerous.
#define CHECKED_PTR_OVERLOAD_COMPARATOR(OP) \
template<typename Ptr> \
bool operator OP(Ptr& p) { return pos OP &*p; }
CHECKED_PTR_OVERLOAD_COMPARATOR(==)
CHECKED_PTR_OVERLOAD_COMPARATOR(<)
CHECKED_PTR_OVERLOAD_COMPARATOR(>)
CHECKED_PTR_OVERLOAD_COMPARATOR(<=)
CHECKED_PTR_OVERLOAD_COMPARATOR(>=)
#undef CHECKED_PTR_OVERLOAD_COMPARATOR
As the commenters have already said, do not use macros for this. If you want to have a minimal implementation but a complete set comparison functions, I believe Boost.Operators is your best bet. The example shown on the page I linked to is:
struct animal : public boost::less_than_comparable<animal>
{
std::string name;
int legs;
animal(std::string n, int l) : name{std::move(n)}, legs{l} {}
bool operator<(const animal &a) const { return legs < a.legs; }
};
where implementing the single operator< function and having the animal class derive from boost::less_than_comparable<animal> gives you the operators >, <=, and >=.
There are other questions on stackoverflow that are related. See
how to use std::rel_ops to supply comparison operators automatically?
How do boost operators work?
Related
Of course, I know about workaround like this (implemented here) by creating my own class and emulate all operators of the native type, but is there a more elegant way to extend some native type?
If you want to ask why:
It could be useful to create a class with runtime checking for overflow. Also I can create a template like this:
template <class T> class LockFreeVolatileValue: public T {...}
which could be used for any types (now it's only for classes).
Related questions:
C++ derive from a native type
Why can't I inherit from int in C++?
I'm reasonably familiar with all major C++ compilers, and the answer for them is no.
This would require non-trivial work in constructor initializer lists, class layout, etcetera, without a significant enough benefit.
No, the "base" of any class must be a class or struct.
Assuming you actually want to alter the behaviour (e.g. check for over-/underflow in operators +, -, * - I don't think divide is particular bothersome for this particular problem). This means that you have to implement the operators +, - and *, =, +=, -=, *=, ++ and --).
Which you could do by:
template<class T> OverflowDetector
{
private:
T member;
public:
T& operator+(T) { ... };
T& operator-(T) { ... };
explicit T operator T () { return member; }
};
Then use like:
typedef OverflowDetector<int> safe_int;
safe_int si1, si2;
si1 = 7;
si2 = 18;
int x = int(si2);
(Yes, you probably need to have some traits type things and a lot more sophistication to stop people doing OverflowDetector<double> or something like that)
You volatile-lockfree class sounds suspiciously similar to std::atomic<T> - I'm sure you had some other ideas, but still, I'm not sure I see the point in inheriting over just implementing using templates...
I created wrapper for fundamental types:
https://github.com/Speakus/cppFundamentalClass/blob/master/Primitive.hpp
Which really show why impossible to do class which work same way as native type
example code to fail:
val = 1
assert(1 == val || ++val);
assert(1 == val);
This code fail if val is class and pass if val is int.
Hope it helps somebody who plans to inherit from native types from any reason.
Basically I found myself today writing lots of code like below:
#define VAL_1 0
#define VAL_2 1
class A {
public:
void memberA();
void memberB();
...
void write(uin32_t address);
}
void
A::
memberA() {
this->write(VAL_1);
}
void
A::
memberB() {
this->write(VAL_2);
}
...
So basically, I have "pretty" names memberA, memberB for some task that really only does call the same function write with a different argument. The values VAL_0 and VAL_1 are not necessarily known to code using my class. Neither is the implementation detail behind memberA or memberB, although writemight be going public at some point.
Basically, now I'm repeating the same line of code this->write(...) over and over again. I'm looking for a solution that bypasses this step and calls the respective write immediately. A kind of passing on of the function arguments somewhat like a C++ constructor from a base class, possibly with matching arguments:
#define VAL_1 0
#define VAL_2 1
class A {
public:
bool memberA() : write(VAL_1);
bool memberB() : write(VAL_2);
...
bool write(uin32_t address);
}
I'm wondering whether there might be something in Boost.Bind or some clever template-coding that lets me achieve this kind or thing?
Thanks,
FRob
If you make your memberX functions inline in the class definition, and if you avoid the redundant this reference, then you don't have too much extra to write:
Your desired (incorrect) syntax:
bool memberA() : write(VAL_1);
The actual (correct) syntax:
bool memberA() { return write(VAL_1); }
If you want to minimize your repetitive code, you could use the pre-processor:
#define F(l, n) bool l() { return write(n); }
F(memberA, VAL_1)
F(memberB, VAL_2)
#undef F
Further, you could use the preprocessor token-pasting operator ##:
#define F(l, n) bool member##l() { return write(VAL_##n); }
F(A, 1)
F(B, 2)
#undef F
Without fully understanding what you are after (I got confused about the last part involving constructors), I think you might be trying a little too hard to make the syntax easier on your clients.
... how about simply:
class A {
public:
enum Value {val1, val2, val3, val4, etc};
bool write(Value val);
};
It's good that you are trying to establish an easier syntax, but you also have to avoid the danger of monolithism. Monolithic classes are something that I strongly believe is one of the most common mistakes in object-oriented design. Sutter goes into this in detail in C++ Coding Standards and on gotw: http://www.gotw.ca/gotw/084.htm.
If you have a class with 100 member functions, you probably have about 80 too many.
^ Think about this statement for a while. When you have so many functions, your classes tend to become increasingly hard to manage. It also invites other developers to just keep adding more and more to your class so that its design is never finalized. The result is the never-ending class that just grows and grows with each development cycle with no end in sight. That can easily become a source of bugs, inefficiencies, constant public interface revisions, unit test breakages, and it can go against the general reuse and flexibility of your class. When you have a separate function per value you can pass to another function, you're dangerously treading into that territory.
Trying too hard to avoid syntactical redundancy is usually a mistake. Unfortunately C++ just requires more lengthy syntax in some cases (getting much better with C++11). What you should try to optimize away is logical redundancy. Here calling write method with various values involves no logical redundancy, and the syntactical overhead is barely more than calling different functions for each value you can possibly pass to write.
If these functions do nothing more than simplify the syntax of passing various values, you have to come to the realization that you are also bloating the class's public interface with a whole lot more functions that, if you are in a production environment, you will likely have to document and teach individually. Strive for doing more with less and I think you'll be much better off.
Try to keep this aspect of monolithism in mind as a priority. You might even go so far as to hoist the named constants out of the class definition as non-members, like so:
class A {
bool write(uint32_t address);
};
// elsewhere
static const uint32_t address_val1 = ...;
static const uint32_t address_val2 = ...;
static const uint32_t address_val3 = ...;
There's actually nothing wrong with this design and, in fact, it has more desirable engineering characteristics than the one where you have more class members as it's completely decoupled from your class, making the maintenance of that class easier, its interface simpler to teach and document, and more likely to meet a state of reasonable completion.
Suppose I have a list of type list<boost::any> that has some type in it that is unknown. Now suppose I want to apply some operation to the elements in the list that is polymorphic. In this case, consider the + operator. Suppose that I know that the list will always contain a homogenous set of objects that support operator+, and I want to get the result of applying operator+ (the "sum" in one sense) between each element of the list into a new boost::any. Something like this:
boost::any sum(list<boost::any> lst) {
// return lst[0]+lst[1]+lst[2] etc
}
Without enumerating all possible types that could support operator+, is there a way to do this? I'm extremely open to crazy ideas.
(I really do have an ok reason for doing this... I'm implementing an interpreter)
You could use boost::variant instead if you know the range of possible types in the list.
I don't see how you can do this without a mesh of operator+ functions to handle every possible combination of contained types, or regular runtime polymorphism.
What is the concrete type you wish to see in the final boost::any output, I wonder?
btw if you are implementing an interpreter, check out Boost.Spirit which might illuminate your design problem here.
C++ matches functions (and operators are merely fancy functions that have an additional infix syntax) by their types, not by their names, at compile-time. (Rather than checking at run-time whether the objects involved support the requested operation.)
The only exception to that I can think of is virtual functions. If the types were polymorphic, you could use any of the workarounds for missing multi-methods (double dispatch). But since they can be anything, I don't think you can do this.
If you have a limited set of types, template-meta programming might help the generate functions implementing addition. But if the number of types involved were limited, you'd probably use boost::variant.
(IME saying this means that, in very short time, someone comes along and proves me wrong.)
No. Not with boost::any nor with boost::variant (doesn't qualify your, "Without enumerating all possible types that could support operator+," requirement).
What you need to do is make your own. The concept behind boost::any is quite simple. If you look at the documentation they have a link to an article explaining the technique (it's basically the handle/body idiom with polymorphism). All you need to do is decide what interface your various objects must have and write the 'any' interface and it's impl accordingly. Something resembling something like so:
struct my_any
{
template < typename T >
my_any(T const& t) : pimpl(new impl<T>(t)) {}
...
some_type get_some_type() const;
...
private:
struct impl_base
{
....
virtual some_type get_some_type() const = 0;
};
template < typename T >
struct impl : impl_base
{
some_type get_some_type() const { return t.get_some_type(); }
impl(T const& t_var) : t(t_var) {}
....
};
boost::scoped_ptr<impl_base> pimpl;
};
some_type operator+ (my_any const& a, my_any const& b)
{
return a.get_some_type() + b.get_some_type();
}
It's hard to imagine what operator+ would do on generic types so I made something up that makes a small amount of sense to me. You'll of course need to change to your needs.
Consider the following piece of code:
class B {
private:
// some data members
public:
friend bool operator==(const B&,const B&);
friend ostream& operator<<(ostream&,const B&);
// some other methods
};
template <typename T=B>
class A {
private:
// some data members
vector<vector<T> > vvlist;
public:
// some other methods
};
My requirement is that the type T that is passed as type parameter must provide definitions for the operator== and the operator<< methods. I do not want to enforce any other restrictions on T.
How can I do this?
One way that I can think of is to Create an Abstract class say "Z" that declares these two methods.
and then write
vector<vector<Z> > vvlist;
and NOT have class A as a template.
Is there a better way to do this?
It happens automatically.
If your code calls the operators == and <<, then the code simply won't compile if the class is passed a type that doesn't define these operators.
It is essentially duck-typing. If it looks like a duck, and quacks like a duck, then it is a duck. It doesn't matter whether it implements an IDuck interface, as long as it exposes the functionality you try to use.
It seems like you are looking for a concept check library. See what Boost has to offer: Boost Concept Check Library. That link also has a good explanation what concepts are. Quote:
A concept is a set of requirements
(valid expressions, associated types,
semantic invariants, complexity
guarantees, etc.) that a type must
fulfill to be correctly used as
arguments in a call to a generic
algorithm
In your question, the concept is "type T must provide operator== and operator<<".
You can write a private method in A that would test required stuff on T in compile time.
void TestReq(T x, T y)
{
if (x==y)
cout << x;
}
This way even plain integers would pass and work.
Background
I have a container class which uses vector<std::string> internally. I have provided a method AddChar(std::string) to this wrapper class which does a push_back() to the internal vector. In my code, I have to add multiple items to the container some time. For that I have to use
container.AddChar("First");
container.AddChar("Second");
This makes the code larger. So to make it more easier, I plan to overload operator <<. So that I can write
container << "First" << "Second"
and two items will get added to underlying vector.
Here is the code I used for that
class ExtendedVector
{
private:
vector<string> container;
public:
friend ExtendedVector& operator<<(ExtendedVector& cont,const std::string str){
cont.AddChar(str);
return cont;
}
void AddChar(const std::string str)
{
container.push_back(str);
}
string ToString()
{
string output;
vector<string>::iterator it = container.begin();
while(it != container.end())
{
output += *it;
++it;
}
return output;
}
};
It is working as expected.
Questions
Is operator overload written correctly?
Is it a good practice to overload operators in situations like this?
Will there be any performance issues or any other issues with this code?
Any thoughts?
Edit
After hearing the excellent comments, I decided not to overload << as it doesn't make sense here. I removed the operator overload code and here is the final code.
class ExtendedVector
{
private:
vector<string> container;
public:
ExtendedVector& AddChar(const std::string str)
{
container.push_back(str);
return *this;
}
.. other methods
}
This allows me to add
container.AddChar("First").AddChar("Second")
In C#, I can do this more easily by using the params keyword. Code will be like
void AddChar(params string[] str)
{
foreach(string s in str)
// add to the underlying collection
}
I know in C++, we can use ... to specify variable langth of parameters. But AFAIK, it is not type safe. So is it a recommended practice to do so? So that I can write
container.AddChar("First","Second")
Thanks for the replies.
Is operator overload written correctly?
It is, but one can do better. Like someone else mentioned, your function can be defined entirely out of existing, public functions. Why not make it use only those? Right now, it is a friend, which means it belongs to the implementation details. The same is true if you put operator<< as a member into your class. However, make your operator<< a non-member, non-friend function.
class ExtendedVector {
...
};
// note, now it is *entirely decoupled* from any private members!
ExtendedVector& operator<<(ExtendedVector& cont, const std::string& str){
cont.AddChar(str);
return cont;
}
If you change your class, you will not be sure that that your operator<< will still work. But if your operator<< entirely depends only on public functions, then you can be sure that it will work after changes were made to implementation details of your class only. Yay!
Is it a good practice to overload operators in situations like this?
As another guy said again, this is arguable. In many situations, operator overloading will look "neat" at first sight, but will look like hell next year, because you have no clue anymore what you had in mind when giving some symbols special love. In the case of operator<<, i think this is an OK use. Its use as an insertion operator for streams is well known. And i know of Qt and KDE applications that use it extensively in cases like
QStringList items;
items << "item1" << "item2";
A similar case is boost.format which also reuses operator% for passing arguments for placeholders in its string:
format("hello %1%, i'm %2% y'old") % "benny" % 21
It's of course also arguable to use it there. But its use for printf format specifies are well known and so its use is OK there too, imho. But as always, style is also subjective so take it with a grain of salt :)
How can i accept variable length arguments in a typesafe way?
Well, there is the way of accepting a vector if you are looking for homogeneous arguments:
void AddChars(std::vector<std::string> const& v) {
std::vector<std::string>::const_iterator cit =
v.begin();
for(;cit != v.begin(); ++cit) {
AddChar(*cit);
}
}
It's not really confortable to pass it though. You have to construct your vector manually and then pass... I see you already have the right feeling about the vararg style functions. One should not use them for this kind of code and only when interfacing with C code or debugging functions if at all. Another way to handle this case is to apply preprocessor programming. This is an advanced topic and is quite hacky. The idea is to automatically generate overloads up to some upper limit roughly like this:
#define GEN_OVERLOAD(X) \
void AddChars(GEN_ARGS(X, std::string arg)) { \
/* now access arg0 ... arg(X-1) */ \
/* AddChar(arg0); ... AddChar(arg(N-1)); */ \
GEN_PRINT_ARG1(X, AddChar, arg) \
}
/* call macro with 0, 1, ..., 9 as argument
GEN_PRINT(10, GEN_OVERLOAD)
That is pseudo code. You can have a look at the boost preprocessor library here.
Next C++ version will offer far better possibilities. Initializer lists can be used:
void AddChars(initializer_list<std::string> ilist) {
// range based for loop
for(std::string const& s : ilist) {
AddChar(s);
}
}
...
AddChars({"hello", "you", "this is fun"});
It's also possible in next C++ to support arbitrary many (mixed-type) arguments using variadic templates. GCC4.4 will have support for them. GCC 4.3 already partially supports them.
1) Yes, except since AddChar is public there's no reason it needs to be a friend.
2) This is arguable. << is sort of in the position of being the operator whose overloading for "weird" things is at least grudgingly accepted.
3) Nothing obvious. As always, profiling is your friend. You may want to consider passing the string parameters to AddChar and operator<< by const reference (const std::string&) to avoid unnecessary copying.
Is it a good practice to overload
operators in situations like this?
I don't think so. It's confusing as hell for someone who doesn't know that you've overloaded the operator. Just stick to descriptive method names and forget about the extra characters you're typing, its just not worth it. Your maintainer (or you yourself in 6 months) will thank you.
I'd prefer not to overload it that way personally because vectors don't normally have an overloaded left shift operator - it's not really it's idiom ;-)
I'd probably return a reference from AddChar instead like so:
ExtendedVector& AddChar(const std::string& str) {
container.push_back(str);
return *this;
}
so you can then do
container.AddChar("First").AddChar("Second");
which isn't really much bigger than bitshift operators.
(also see Logan's comment about passing strings in by reference instead of by value).
The operator overloading in this case is not good practice as it makes the code less readable. The standard std::vector doesn't have it either for pushing elements, for good reasons.
If you're worried about the caller code being too long, you could consider this instead of the overloaded operator:
container.AddChar("First").AddChar("Second");
This will be possible if you have AddChar() return *this.
It's funny that you have this toString() function. In that case, an operator<< to output to a stream would be the standard thing to use instead! So if you want to use operators make the toString() function an operator<<.
The operator is not correctly overloaded here. There is no reason to make the operator a friend since it can be a member of the class. Friend is for functions which are not actual members of the class (such as when overloading << for ostream so the object can be output to cout or ofstreams).
What you actually want the operator to be:
ExtendedVector& operator<<(const std::string str){
AddChar(str);
return *this;
}
It is usually considered bad practice to overload operators in a way that has them do something than they do normally. << is normally bit shift, so overloading it this way can be confusing. Obviously STL overloads << for "stream insertion" and so along with that it might make sense to overload it for your use in a similar way. But that doesn't seem like what you're doing, so you probably want to avoid it.
There are no performance issues since operator overloading is the same as a regular function call, just the call is hidden because it is done automatically by the compiler.
This is going to make things rather confusing, I would use the same syntax as std::cin into a variable:
std::cin >> someint;
"First" >> container;
This way it is at least an insertion operator. To me when anything has a << overloaded operator I expect it to be outputting something. Just like std::cout.