I have this:
typedef string domanin_name;
And then, I try to overload the operator< in this way:
bool operator<(const domain_name & left, const domain_name & right){
int pos_label_left = left.find_last_of('.');
int pos_label_right = right.find_last_of('.');
string label_left = left.substr(pos_label_left);
string label_right = right.substr(pos_label_right);
int last_pos_label_left=0, last_pos_label_right=0;
while(pos_label_left!=string::npos && pos_label_right!=string::npos){
if(label_left<label_right) return true;
else if(label_left>label_right) return false;
else{
last_pos_label_left = pos_label_left;
last_pos_label_right = pos_label_right;
pos_label_left = left.find_last_of('.', last_pos_label_left);
pos_label_right = right.find_last_of('.', last_pos_label_left);
label_left = left.substr(pos_label_left, last_pos_label_left);
label_right = right.substr(pos_label_right, last_pos_label_right);
}
}
}
I know it's a strange way to overload the operator <, but I have to do it this way. It should do what I want. That's not the point.
The problem is that it enter in an infinite loop right in this line:
if(label_left<label_right) return true;
It seems like it's trying to use this overloading function itself to do the comparision, but label_left is a string, not a domain name!
Any suggestion?
typedef just gives another name for a type. It does not create a distinct type. So in effect, you're overloading operator < for string.
If you want to create a distinct type, then you can try
struct domain_name {
string data;
// ...
};
and work with that.
Typedef doesn't work like this. Typedef simply defines an alias for the type - it is still a string. In order to do this, you would need a new type instead. You should do this anyway. Your operator is overloading the comparison operator for all strings.
Your typedef doesn't create a new type. It just creates a new name to refer to the same type as before. Thus, when you use < inside your operator function on two strings, the compiler just uses the same operator it's compiling because the argument types match.
What you may wish to do instead is define an entirely new function:
bool domain_less(domain_name const& left, domain_name const& right);
Then use that function in places that call for a comparison function, such as std::sort. Most of the standard algorithms will use < by default, but allow you to provide your own predicate function instead. You may need to use std::ptr_fun to wrap your function. You can also write your own functor object; it's typical to descend from std::binary_function in that case. (Check out the <functional> header.)
Related
Can anyone guide me on how to solve this problem.
I have a boost::variant.
typedef boost::variant <
int,
std::string,
bool,
double,
vector<int>,
vector<string>,
vector<bool>,
vector<double>
> boostVar;
I am trying to create overload [] operator as member function of a class ABC something like this (this is just a dummy implementation)
class ABC
{
//some map of (key, value) pair that where key is string and value is of type boostVar
boostVar [](const string key)
{
boostVar temp;
//some operation that fills up temp based on value of key
return temp;
}
}
So while retrieving the a particular value using this implementation, it forces user to specify
int key1Val = boost::get<int>(ABC["KEY1"]);
bool key2Val = boost::get<bool>(ABC["KEY2"]);
vector<int> key3Val = boost::get<vector<int>>(ABC["KEY3"]);
my question is:
How should I go about implementing this if I want to access the values like below (i.e. without boost::get<>)
int key1Val = ABC["KEY1"];
bool key2Val = ABC["KEY2"];
vector<int> key3Val = ABC["KEY3"];
The implementation should give warning to user if the say: KEY1 does not match int, KEY2 does not match bool and so on.
You'd need to use a class to wrap the boost variant and add the conversion behaviours. At it's simplest - in the common case where realistically client code won't be trying to delete dynamically allocated instances using pointers to the base (boost::variant<...>*) - it could look something like this:
struct Variant : boost::variant<int, std::string, ...etc...>
{
operator int() const { return boost::get<int>(*this); }
operator std::string() const { return boost::get<std::string>(*this); }
...etc...
};
This will provide the same checks get<> provides: compile time checks that you're trying to assign to one of the types the variant could hold at runtime, and runtime checks that it does actually hold the exact destination type when you try to assign from it.
If you can't be sure client code won't delete via the base class pointer, consider private inheritance or composition (you will need to do more work to expose any other variant functionality your client code may want to access).
(ABC::operator[](const std::string& key) const can just return such a Variant).
There are two integers x and 7 which are randomly generated integers. The program uses a red black tree member fucntion insert to insert new values into the tree.
I'm not understand the arguments of the insert function, more specifically the use of
(void*)x and (void*y)
Here's the function call in main
rbt.rbtree_insert(t, (void*)x, (void*)y, compare_int);
Here's the insert function defined
void RBTree::rbtree_insert(rbtree t, void* key, void* value, compare_func compare)
{
node inserted_node = new_node(key, value, RED, NULL, NULL);
if (t->root == NULL)
{
t->root = inserted_node;
}
else
{
node n = t->root;
while (1)
{
int comp_result = compare(key, n->key);
if (comp_result == 0)
{
n->value = value;
return;
}
else if (comp_result < 0)
{
if (n->left == NULL)
{
n->left = inserted_node;
break;
}
else
{
n = n->left;
}
}
else
{
assert(comp_result > 0);
if (n->right == NULL)
{
n->right = inserted_node;
break;
}
else
{
n = n->right;
}
}
}
inserted_node->parent = n;
}
insert_case1(t, inserted_node);
verify_properties(t);
}
void* is a type. More specifically, it is a pointer type. Even more specifically, it is a special pointer type that can point to any type. void* is a way to implement polymorphism in C. It's usually not recommended to use void* in C++.
(void*)x is an explicit type conversion also known as C-style type cast expression. The type of variable x is converted to void*. The use of C-style casts is discouraged in C++.
Presumably the type of x is not void* and therefore a conversion is needed to match the type of the argument.
The author of this code uses the most abstract pointer type available in C++: void*. It is a pointer so "something". What this "something" might be is not defined at compile time. (void*)x is a type cast in legacy C-syntax, that interprets any other pointer as void*. The prefered C++ syntax is static_cast<void*>(x), though void* should only be used, when there are very, very good reasons to do so.
I understand, that this is legacy code, you have been asked to work on. So let's be frank, there is quite a lot wrong with it.
There are exactly two reason to implement a red-black-tree class: learning data structures and std::map<> as part of a standard library implementation. In all other cases, there is no reason not to prefer std::map<>. It'd save you from all the design pitfalls, the author of this code has stepped in.
It is redundant to add the name of the class to the name of a member function. Call it RBTree::insert() instead of RBTree::rbtree_insert(). When you use consistent member function names for different container types, you can easily exchange them in future, without having to change all the calls to all the member functions. The standard containers are a good source of inspiration here.
A red-black-tree instance always has to work with the same compare function. To pass the compare function again and again to insert(), find(), erase(), etc. is not only redundant but also error prone. Either have it as a parameter to the constructor, or better as a template parameter to a red-black-tree class template.
In any case a red-black-tree should be a template, that has a key and a value type as template parameters. Then all the member functions like insert(), find(), etc. can be typesafe.
Why should one pass the this object explicitly to a member function. I guess, the author of that code has been trying to write Python in C++. In C++ this is always implicit for member functions, in contrast to self in Python.
Putting it all together I'd propose an interface like this:
template<typename key_t,
typename value_t,
typename Compare = std::less<key_t>>
class rb_tree {
void insert(const key_t& key, const value_t& value);
void erase(const key_t& key);
value_t find(const key_t& key);
};
As you see, we now define types for keys and values and use them in insert(), erase() and find(). These functions can never try to walk a tree with int keys as if it had std::string keys. They also always use the same compare function, which defaults to the operator <.
The usage is a lot better to understand as well:
rb_tree<int, int> rbt; // we use the default comparison
int x = 42;
int y = 4711;
rbt.insert(x, y);
assert(rbt.find(x) == y);
rbt.erase(x);
Well, actually my real suggestion is to drop than homegrown red-black-tree and use std::map<> instead. Its usage is even more intuitive:
std::map<int, int> rbt;
int x = 42;
int y = 4711;
rbt[x] = y;
assert(rbt[x] == y);
rbt.erase(x);
In C++11, what is the best way to provide two versions of a method, one to modify the object itself and one to return a modified copy?
For example, consider a string class which has the "append(string)" method. Sometimes you might want to use append to modify your existing string object, sometimes you might want to keep your string object the same and create a copy.
Of course, I could just implement the first version and manually create a new object everytime I need one but that adds multiple temporary variables and lines of code to my project.
If it is still not clear what I am trying to do:
String s1("xy");
String s2 = s1.appendCopy("z");
s1.appendThis("w");
// s1 == "xyw"
// s2 == "xyz"
In Ruby there is a concept (or rather, a naming convention) which says for such methods, there are two variants: append (creates a new String) and append! (modifies this object)
C++ does not have something like this, so I would be stuck with ugly method names like "appendCopy".
Is there a good way to implement what I am trying to do?
So far, the best idea I had would be to make the modifying versions class members and the copying/immutable versions static methods which take the object to work on as a const argument.
There is actually a guideline, expressed by Herb Sutter in GotW #84:
Prefer non-member non-friend functions.
In your specific case, append (in-place) requires modifying the existing string so is well-suited to be a class-method, while append (copying) does not, so (following the guideline) should not be a class-method.
Thus:
void std::string::append(std::string const&);
inline std::string append(std::string left, std::string const& right) {
left.append(right);
return left;
}
After popular request, here are two overloads that can be used to optimize performance. First the member-version that may reuse its argument's buffer:
void std::string::append(std::string&& other) {
size_t const result_size = this->size() + other.size();
if (this->capacity() < result_size) {
if (other.capacity() >= result_size) {
swap(*this, other);
this->prepend(other);
return;
}
// grow buffer
}
// append
}
And second the free-function that may reuse its right-hand buffer:
inline std::string append(std::string const& left, std::string&& right) {
right.prepend(left);
return right;
}
Note: I am not exactly sure there are not ambiguous overloads manifesting. I believe there should not be...
With the new move semantics you can write:
class A{
public:
// this will get the property
const dataType& PropertyName() const { return m_Property; }
// this wil set the property
dataType& PropertyName() { return m_Propery; }
private:
dataType m_Propery;
};
main()
{
A a;
a.PropertyName() = someValueOfType_dataType; // set
someOtherValueOfType_dataType = a.PropertyName(); // get
}
I'm currently writing a compiler front end for personal education on the topic and I've run into a problem concerning the way I handle BNF definition in C++ through operator overloading.
Currently my setup is as follows:
Rule.h:
class Rule
{
public:
ChainRule operator>>(Rule& right);
OrRule operator|(Rule& right);
KleeneRule operator*();
OptionalRule Rule::operator+();
virtual bool parse(TokenList::iterator& begin, TokenList::iterator end) = 0;
};
Rule.cpp:
ChainRule Rule::operator>>(Rule& right) {
return ChainRule(this, &right);
}
OrRule Rule::operator|(Rule& right) {
return OrRule(this, &right);
}
KleeneRule Rule::operator*() {
return KleeneRule(this);
}
OptionalRule Rule::operator+() {
return OptionalRule(this);
}
ChainRule, OrRule, KleeneRule, OptionalRule and EmptyRule are defined trivially like so:
class ChainRule : public Rule
{
private:
Rule* next;
Rule* _this;
public:
ChainRule();
ChainRule(Rule* _this, Rule* right);
bool parse(TokenList::iterator& begin, TokenList::iterator end) override;
};
Each subclass of Rule obviously defines a resonable implementation of parse(). Using these classes I can define my grammar as follows:
OrRule assignment_exp = logical_or_exp
| unary_exp >> StringRule("=") >> assignment_exp
;
Now here's the problem: Each overloaded operator returns a new object by value. This means that whenever I use operator>> or operator| from the Rule class, these pointers will be garbage once I return from the call to operator>> or operator| since the stack has been cleaned up and the objects are gone.
Neither can I use pass by value in the constructors for my Rule subclasses since this would not allow me to define recursive grammars.
So I'm left with no option of passing objects by value, and no option of passing objects by pointers. Can anyone point me to a solution that would not force me to define my grammar like so?
StringRule s = StringRule("=");
OrRule assignment_exp;
ChainRule temp1 = s >> assignment_exp;
ChainRule temp2 = unary_exp >> temp1;
assignment_exp = logical_or_exp | temp2;
P.S. I am aware of the various parser generators and Boost.Spirit, but my goal is to write my own parser.
You can allocate the return objects on the heap (via a factory) and return them as references. The factory can keep track of them so you won't leak. As far as syntax is concerned it will work the same as when you return them by value.
You can get around this problem by replacing your Rule* (which have the problem that you cannot overload operators for them) with wrapper objects. I.e. ChainRule would contain RuleRef next instead of Rule * next, etc., and all the operators would be defined for RuleRef. RuleRef would simply contain a Rule*, and be constructable from a Rule*. To make memory handling easier, you could inherit from a smart pointer class.
Say I have a type with a member function:
class Thing {
std::string m_name;
public:
std::string & getName() {
return m_name;
}
};
And say I have a collection of that type:
std::vector<Thing> things;
And I want to keep the things in order by name. To do that, I use std::lower_bound to figure out where to put it:
bool thingLessThan(Thing const& thing, std::string const& name) {
return thing.getName() < name;
}
void addThing(std::string const& name) {
vector<Thing>::iterator position = lower_bound(
things.begin(), things.end(),
name,
thingLessThan);
if (position == things.end() || position->getName() != name) {
position = things.insert(position, Thing());
position->getName() = name;
}
}
Is there a way to do the same thing as the thingLessThan function without actually creating a function, perhaps using std::mem_fun, std::less, etc?
Other than a lambda you can simply define an operator< which adheres to strict weak ordering to allow a container of your object to be comparable by STL algorithms with the default predicate std::less
class whatever
{
public:
bool operator<(const whatever& rhs) const { return x < rhs.x; }
private:
int x;
};
std::vector<whatever> v;
std::sort(v.begin(), v.end());
Sure. You can use a lambda expression (assuming your compiler supports it):
vector<Thing>::iterator position = lower_bound(
things.begin(), things.end(),
name,
[](Thing const& thing, std::string const& name) { return thing.getName() < name; });
Of course, an alternative option is just to define operator< for the class, then it will be used by default, if you don't specify another comparer function for std::lower_bound.
Depending on what your purpose is? If you just like the syntactic niceness of not declaring something to be used in one place, use lambda expressions to create an anonymous function.
You can overload operator<() and use std::less<T> if you don't want to write predicates contantly. Also you can use lambda-expressions, which would be much nicer, because operator<() is logically connected only with things, that can be put in some order in obvious ways, like numbers or strings.
If you use a std::map, the strings will be placed in alphabetical order automatically. If you want to modify the ordering further, create your own key comparison function. I think this would be the simplest option.
To use a std::list, you can write your own comparison code inside of the addThing() function that goes through the list looking at each string and inserts the new one at the appropriate place.