I wrote my own vector and stack, they are class template,both works fine,now I want to Specializes the std::swap algorithm for my stack,so I defined a function template swap as friend of vector, it uses the swap inside vector.then I defined a swap member function in stack.but if I try to call that swap function, it can't compile. the vs2019 says the "the swap function doesn't accept two arguments". I thought the swap inside stack class would use argument dependent lookup,but it didn't do that.please help me,what is the right way to do it? thanks a lot. some code of vector and stack are below
Vector.h
template<class Object>
void swap(Vector<Object>& lhs, Vector<Object>& rhs) {
lhs.swap(rhs);
}
template<class Object>
class Vector {
//.....
friend void swap<>(Vector<Object>& lhs, Vector<Object>& rhs);
public:
//...
void swap(Vector &rhs){
//....
}
}
Stack.h
#include"Vector.h"
template<class Object,class Container>
class Stack {
//......
void swap(Stack &other) {
swap(container, other.container);
}
main.cpp
//....
int main() {
//....
Stack<int,Vector<int>>s1,s2;
s1.swap(s2);
}
//....
It's a simple case of name hiding: In the Stack class the name swap is Stack::swap.
If you want to use some other function you need to provide an explicit scope, as in
::swap(container, other.container);
Note the use of the :: scoping operator to use the swap function from the global scope.
Here:
void swap(Stack &other) {
swap(container, other.container);
}
You are calling swap from itself. You don't want that. To make it so ADL finds the right swap function, you can try this:
// outside the class
template <typename T>
void MySwap(T& a1, T& a2) {
using std::swap; // may not be needed in your case
swap(a1, a2);
}
// in the class
void swap(Stack &other) {
MySwap(container, other.container);
}
The name swap inside MySwap cannot possibly refer to Stack::swap, so it will use ADL to find the correct overload.
For more on why using std::swap is useful but possibly unnecessary in your case, see: https://en.cppreference.com/w/cpp/named_req/Swappable
Related
I created a class bigInt in c++. While overloading some of its operators, I need to pass the object itself as an argument to one of its member functions. I know that I can do this with *this. I can also do it by creating another object of the same class with the same member variables and pass it as an argument. But is there any way I can skip *this and also not create another object?
Here is the code I have made using *this:
using namespace std;
class bigInt {
private:
string value;
public:
template<class T>
bigInt(T x) {
//.... .... ....constructor
}
bigInt operator+ (bigInt num) {
//... ... ... my code here
}
template<class T>
bigInt operator+ (T x) {
return *this + bigInt(x);
}
};
And here is the code where I created another object of the class bigInt:
using namespace std;
class bigInt {
private:
string value;
public:
template<class T>
bigInt(T x) {
//.... .... ....constructor
}
bigInt operator+ (bigInt num) {
//... ... ... my code here
}
template<class T>
bigInt operator+ (T x) {
return bigInt(value) + bigInt(x);
}
};
Please tell me how I can do the same thing without using *this or creating another object?
N.B. I heard that using the this pointer is generally considered a bad programming practice. Is it true or not? If it is true, is there any case where it is not considered a bad practice?
Update: It's perfectly okay to use *this in this context. The article that inspired me to ask this question was talking about something else completely. But as a newbie programmer, I didn't understand the context there.
The templated operator+ is superfluous; just remove it.
In other news:
Consider also changing bigInt operator+ (bigInt num) to bigInt operator+ (bigInt const& num) to avoid needless inefficiency.
Also, consider making it a friend function so that order of arguments doesn't matter.
I have a quick question for my program: How can I call this template function with Set, rather than int?
I have a class here called Set
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class Set
{
public:
class Iterator;
void add(T v);
void remove(T v);
Iterator begin();
Iterator end();
private:
vector<T> data;
};
Here's my cpp:
Unfortunately, main cannot be a template function so I had to make another function addstuff, which main calls
template <class T>
Set<T> addstuff()
{
Set<T> a;
a.add(1);
a.add(2);
a.add(3);
a.add("a string");
return a;
}
void main()
{
addstuff<Set>(); //<< Error here. If I use addstuff<int>(), it would run but
//I can't add string to it. I am required to be able to add
//different data types to this vector
}
Your writing addstuff<Set>() would be an attempt to resolve to Set<Set> addstuff() which is meaningless.
addstuff<std::string>() would allow you to add std::strings to your set, but then a.add(1) would fail since the literal cannot be implicitly converted to a string type.
addstuff<int>() does work but that's a merry coincidence. add(1) has the correct type in that instance to be added to Set<int>.
You could build a class Foo that has non-explicit constructors to a string and an integer and make that your template type: addstuff<Foo>(). But I'm not convinced that's what your professor wants you to do and there are better ways of solving this (type erasure for one, but this is getting quite involved).
I'm working on some code and I have a section where I do a one off sort function. To implement it I decided it was easiest to overload the operator< function. What I would prefer to do is move the implementation of the sort closer to the actual call by using some sort of boost::bind, boost::phoenix, lambda or some other type of implementation. Unfortunately I don't have access to new C++11 functionality. Below is some example code.
// In a header
struct foo
{
char * a;
char * c_str() { return a; }
}
// In a header
struct bar
{
foo * X;
bar(foo * _X) : X(_X) {}
bool operator < (const bar& rhs) const
{
return std::string(X->c_str()) < std::string(rhs.X->c_str());
}
};
struct bars : public std::vector<bar> { ... some stuff };
// Some other header
bars Bs;
// A cpp file
... other stuff happens that fills the Xs vector with objects
...::Function()
{
// Current use and it works fine
std::sort(Bs.begin(), Bs.end())
// Would like something that accomplishes this:
// std::sort(Bs.begin(), Bs.end(),
// std::string(lhs.X->c_str()) < std::string(rhs.X->c_str()))
// A non-working example of what I'm trying to do
// std::sort(Xs.begin(), Xs.end(),
// std::string((bind(bar::X->c_str(), _1)) <
// std::string((bind(bar::X->c_str(), _2)) )
}
I get lost when trying to figure out how to access the member pointers, member function and then cast the result all within a boost::bind function.
Thank you for your help.
I'm sure you can twist your way out of this using ample helpings of
Boost Phoenix bind and lambda
Boost Bind protect
However, I've learned to avoid these situations. Edit In fact, see below for one such contraption. I find this very very error prone and hard to reason about.
What you're seeing is, in essence, a violation of the Law Of Demeter. If you "just" wrote the code (not in a lambda), already it would be handling too many tasks.
So the first thing I'd do is rethink the class design.
The second thing I'd do is /extract/ different responsibilities from your comparator. Notice, that the comparator does three things:
access the c_str() of the X in lhs
access the c_str() of the X in rhs
compare the two
The first two steps are clear candidates for extraction. Let's write the generic comparer that remains first:
template <typename F>
struct compare_by_impl {
compare_by_impl(F f = F{}) : _f(std::move(f)) {}
template <typename T, typename U>
bool operator()(T const& a, U const& b) const {
return _f(a) < _f(b);
}
private:
F _f;
};
As always, it's nice to have factory function that will deduce the accessor type (in case you can get away with just using Phoenix there, it will save you specifying the (arcane) typenames involved in the expression templates):
template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor&& f) {
return compare_by_impl<Accessor>(std::forward<Accessor>(f));
}
Now you could already move the implementation with your sort call:
void Function()
{
struct accessX_c_str {
std::string operator()(bar const& b) const {
return b.X->c_str();
}
};
std::sort(Bs.begin(), Bs.end(), comparer_by(accessX_c_str()));
}
I'd personally leave it there.
Here's some more twisted contraptions:
// to avoid `comparer_by`
std::sort(Bs.begin(), Bs.end(), phx::bind(accessX_c_str(), arg1) < phx::bind(accessX_c_str(), arg2));
// to avoid any helper types (!?!?!? untested!)
std::sort(Bs.begin(), Bs.end(),
phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg1)))
< phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg2)))
);
I have a class with a function
MyClass::doStuff(std::vector<MyCustomData*> toSort) { ...
in which I call
std::sort(toSort.begin(), toSort.end(), MyClass::SortByZ());
myClass::SortByZ() is a custom comparator.
Now this works but I would like to achieve the following:
I have several classes, which should each have its own comparator functor to sort "MyCustomData". So e.g. Class1... should have
class Class1 {
struct SortData {
bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
return lhs->something1 > rhs->something1;
}
};
//...many more functions/vars
}
while Class2 has a different comparator functor for the same datatype eg
class Class2 {
struct SortData {
bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
return lhs->something2 > rhs->something2;
}
};
//...many more functions/vars
}
Now I would like to be able to call the function MyClass::doStuff(...) with either
doStuff(myData, Class1::SortData)
or
doStuff(myData, Class2::SortData)
and the function MyClass::doStuff(...) should use the respective Sort-Order.
I did not find out a way of doing this, is there one? I would like a simple solution (doesn't have to support templates or anything). I would be willing to use boost if I needed that, but a solution without boost would be preferred.
I hope I was able to describe what I want to achieve? Thanks for any help!
You will have to make doStuff a template:
template <typename Comparator>
void doStuff(std::vector<MyCustomData*> toSort, Comparator compare) {
// ...
std::sort(toSort.begin(), toSort.end(), compare);
// ...
}
Also, it might want to take the first argument by reference. As it is, it will sort a copy of the argument, discard that copy, and leave the caller's vector untouched; although perhaps that's what you want.
Use a function template, in order to accept any kind of comparison function (or functor):
template <typename Comparator>
void doStuff(std::vector<MyCustomData> toSort, Comparator comparator)
{
...
std::sort(toSort.begin(), toSort.end(), comparator);
...
}
...
doStuff(myData, Class1::SortData());
doStuff(myData, Class2::SortData());
This is how standard algorithms provide genericity.
Can anyone provide a simple example of how to use the Boost Intrusive Hashtable? I've tried to implement it, but I'm having little luck.
I have this so far
void HashTableIndex::addToIndex(Message* message)
{
hashtable<MyMessageVector>::bucket_type base_buckets[10000];
hashtable<MyMessageVector> htable(hashtable<MyMessageVector>::bucket_traits(base_buckets, 10000));
boost::array<MyMessageVector,10000> items;
htable.insert_unique(items[0]);
but for some reason it's not calling my Hash function which is defined above like this
size_t HashTableIndex::hash_value(MyMessageVector& b)
{
boost::hash<string> hasher;
return hasher(b.getKey());
};
For some reason it won't call my hash_value function. Any help on this would be much appreciated!
You can supply the hash function to the hash table using boost::intrusive::hash in the list of options.
You are using a member function and boost::hash requires a free function. See boost::hash documentation:
namespace library
{
std::size_t hash_value(book const& b)
{
boost::hash<int> hasher;
return hasher(b.id);
}
}
You can also use a "friend" function declared in the class as shown in the Boost.Intrusive unordered_set documentation:
class MyClass
{
//...
public:
friend bool operator== (const MyClass &a, const MyClass &b)
{ return a.int_ == b.int_; }
friend std::size_t hash_value(const MyClass &value)
{ return std::size_t(value.int_); }
};