C++ Generic Swap Function - c++

In my class.h i got:
template<class T> void Swap(T, T);
And in class.cpp:
template<class T>
void class::Swap(T& p1, T& p2)
{
T aux = p1;
p1 = p2;
p2 = aux;
}
When I try :
this->Swap<char*>(&lit[i][k], &lit[i][l]);
And another question:
What am i doing wrong here: i want to split my string after some delimitators ("+-") and strtok isn't working as I expected.
int counter = 0;
char* s = strtok(eq_clone ," ");
while(s != NULL)
{
counter++;
if(s == "")
counter--;
s = strtok(eq_clone ,"+-");
}

This looks like a mistake as it will never be true:
if(s == "")
this is comparing the address of s to the address of the string literal "": it is not checking if s is an empty string. An alternative to using strtok() would be boost::algorithm::split:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
int main()
{
std::string s("a,string+with-multiple delimiters");
std::vector<std::string> s_tokens;
boost::algorithm::split(s_tokens, s, boost::is_any_of(",+- "));
std::for_each(s_tokens.begin(),
s_tokens.end(),
[] (const std::string& s)
{
std::cout << s << "\n";
});
return 0;
}
Output:
a
string
with
multiple
delimiters
Regarding swap, as has already been stated in comments and other answer(s) just use std::swap(). I am guessing that lit is a char[][] so std::swap(lit[i][k], lit[i][l]); will do exactly what you require.
EDIT:
After comment giving declaration string* lit and that lit appears to be an array (from example usage) then use std::swap() in this manner:
std::string* lit = new std::string[4];
lit[0] = "zero";
std::swap(lit[0][1], lit[0][2]); // The characters will be passed by reference,
// don't take address.
std::cout << lit[0] << "\n"; // Prints "zreo"
Note, that the declaration of your Swap() passes arguments by value (incorrect), but the definition of Swap() passes arguments by reference (correct). If you change the declaration of your Swap() and invoke it as follows it will work (if you really don't want to use std::swap():
template<class T> void Swap(T&, T&);
//^ //^
Swap(lit[i][k], lit[i][l]);

1) Why is Swap() a class member? Class members should somehow be tightly coupled to your classes. In most cases it is is sign of bad design if something, which does not use private members or is very similar to a method that does (i.e. a convinience method), becomes a class member. C++ is not java where everything has to belong to a class. Make your swap() method a free standing template method.
2) Better yet, do not reinvent the wheel. std::swap() is there and it works mightily well. In many cases you can expect the methods and classes provided by the standard library to work better than something you could write up.
3) In your class you called the method Sort(), but the question is about Swap(). Since you did not write what you expected to happen and what actually happens, this is the only thing I can find which might be wrong.
4) Do not use strtok() in C++ unless you have to. char* are C-Style strings and should not be used in C++. Use std::string instead.

Related

Is it possible to add a member to `string` that gives the `int` location of the last `char` put into it?

The one annoyance I have with the std::string class is that the only ways (that I could figure out after reading cplusplus.com's info about it) to get the location of the last character in the string is (stringVariable.length() - 1) or stringVariable.rfind(stringVariable.back()). It'd be nice if I could just do stringVariable.last(). This is for a function I wrote in a personal project that needs to reference this number of a user's input string.
Some ideas I had were creating a struct that is just a string and has the last() function as a member function, or a class that copies the string class and adds that member. With a struct, I'm not sure how (or if it's possible) to make it so I can make the variable assigned to the type automatically reference the string in it so that I don't need to make a constant member call. I'm taking the second C++ class in school right now, but we haven't touched on C++ classes yet.
I tried reading some guides and answers here about classes, and they don't look all that different from structs, but the more complex stuff in either case was Greek to me. I only learned how to use a struct as a holder for multiple variable types; like the name string and id int for a person, or something like that. I learned from the guides I can put functions in them, and define operator behavior too, but when I tried to define operator behavior for the string struct I made, I couldn't get it to work.
Based on the example I read, I tried:
str &operator=(const str &ing)
{
s = ing.s;
return s;
}
But when I tried to test it by using = to copy a str variable to a string variable I could cout, it errors that str can't be converted to string, so I tried a few adjustments, and after getting errors about the & and such, I ended up with:
string operator=(str ing)
{
return ing.s;
}
Which gets the same error. Here's the full struct test program I'm using:
#include <iostream>
#include <string>
using namespace std;
struct str
{
string s;
string operator=(str ing)
{
return ing.s;
}
int last()
{
return s.length() - 1;
}
};
int main()
{
str ing {"Hello World!"};
string i = ing;
cout << i;
return 0;
}
If I could get the = assignment to work, I'd try to get << and such to work with str, too.
If that doesn't turn out to be possible, my fallback is just using a function like:
int last(string str)
{
return str.length() - 1;
}
Edit: For More Info
I was asked many times in the comments what my actual need is for this. In truth it’s just that it annoys me that it doesn’t have that member function. I’m surprised it wasn’t implemented long ago.
Thanks to the commenters I was able to come up with the diabolical workaround of overloading an operator to make a string able to subtract a function to output the result of a string being input to the function. I used - because I was thinking script notation: stringVariable -l or stringVariable -last. Then I can also just use #define to remove the need for the operator, making it stringVariable last() (“last()” instead of “last” because aesthetic).
Another option I figured out was reversing positions and using #define to make it last stringVariable, or #define in - to make it last in stringVariable. Although the simplest version of the operator function for this by far is just defining a negative string as the int output directly. Not that any of that is really better than just using the function normally, but I enjoyed learning about those features of C++.
The single answerer also consolidated much of the commenters advice and brought it to the next level to give me a more elegant version of the idea I had to create my own class with a string that could do all the string stuff and the extra member. However taking the advice of reexamining my needs I think perhaps ‘string’ isn’t the only option I have for a user input container. I definitely need the int output made by stringVariable.size() - 1 with whatever char array I use (since it’s used in mathematical equations), but maybe a vector or something else could do that already?
I was briefly told about vectors in my previous class, but we weren’t allowed to use them. Since this is for a simulated environment I’m doing on my own (that I might use for the basis of a game some day) I can use anything I want though. I also decided to pull an allnighter last night and just started reading about containers at random on cplusplus.com.
So I’m wondering if perhaps a list or deque could work too. I wasn’t really taught about anything other than string and hardcoded arrays (yet) though. I use the string to store the user’s input to simplify the process of avoiding unforeseeable crashing/errors that come from bad user inputs, then just translate the strings to whatever I need with various functions I've written.
creating a struct that is just a string and has the last() function as a member function
That will work just fine, if you don't mind implementing the interfaces needed to convert between std::string <-> str.
Also, be aware that std::string indexes use std::string::size_type, which is not int. size_type is an unsigned type, typically std::size_t. std::string defines an npos constant to indicate "no index", that is what your last() function should return if the std::string is empty, eg:
std::string::size_type last_index() const
{
return !s.empty() ? s.size() - 1 : std::string::npos;
}
But, if you really want to have last() return an int (ie, your std::string will never exceed 2147483647 characters):
int last_index() const
{
return static_cast<int>(s.size()) - 1;
}
With a struct, I'm not sure how (or if it's possible) to make it so I can make the variable assigned to the type automatically reference the string in it so that I don’t need to make a constant member call.
In short, no.
Based on the example I read, I tried:
str &operator=(const str &ing)
{
s = ing.s;
return s;
}
It needs to return a reference to the str object that is being assigned to, not the std::string member that was actually modified, eg:
str& operator=(const str &rhs)
{
s = rhs.s;
return *this;
}
But when I tried to test it by using = to copy a str variable to a string variable I could cout, it errors that str can't be converted to string
Correct, it can't by default. You need to define a conversion operator for that purpose, eg:
operator std::string() const
{
return s;
}
If I could get the = assignment to work, I'd try to get << and such to work with str, too.
Yes, you should, eg:
std::ostream& operator<<(std::ostream &out, const str &rhs)
{
return out << rhs.s;
}
If that doesn't turn out to be possible, my fallback is just using a function
That is a good idea, eg:
std::string::size_type last_index(const std::string &s)
{
return !s.empty() ? s.size() - 1 : std::string::npos;
}
Or:
int last_index(const str::string &s)
{
return static_cast<int>(s.size()) - 1;
}
Here's the full struct test program I'm using
Try this:
#include <iostream>
#include <string>
using namespace std;
class str
{
private:
string s;
public:
str() = default;
str(const string &s) : s(s) {}
str& operator=(const str &rhs)
{
s = rhs.s;
return *this;
}
operator string() const
{
return s;
}
string::size_type last_index() const
{
return !s.empty() ? s.size() - 1 : string::npos;
}
friend ostream& operator<<(ostream &out, const str &rhs)
{
return out << rhs.s;
}
};
string::size_type last_index(const string &s)
{
return !s.empty() ? s.size() - 1 : string::npos;
}
int main()
{
str ing {"Hello World!"};
cout << ing << endl;
cout << ing.last_index() << endl;
string i = ing;
cout << i << endl;
cout << last_index(i) << endl;
return 0;
}

Why does my class std::vector member always throw a segfault?

I've searched endlessly on SE for a logical explanation for why this is happening. It is probably something very simple that I've overlooked, however I cannot spot it and would really appreciate some assistance with this.
Last week I implemented a class to read the output of a system call from a .ini file and then find and store the required information into custom objects that are then stored in a vector inside a Config class. It is a Singleton config class storing a unique_ptr for each instance of my custom class that is created.
The thing is, when I implemented this last week on my laptop, I had zero issues reading and writing to my member vector and was able to get it working exactly how I needed it. Since pulling to my desktop computer, this vector, and any STL container that I use as a member of my class, throws a segmentation fault when I try to do anything on it, even get it's size.
I've tried to shorten the code below to only include sections that actually use this vector. I have replaced my config with A, and custom class with T, and no matter where I try to use my member container, or any other test STL containers that I add to the class, I get a segfault.
For the record, I am using Qt with C++11.
Update: This example breaks on line 50 of c.cpp when debugging, and anywhere that tries to call the vector.
Debug points to this line in stl_vector.h
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const _GLIBCXX_NOEXCEPT
/*-> this line */ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
main.cpp
#include "c.h"
int main(int argc, char *argv[])
{
C *c = C::getInstance();
delete c;
return 0;
}
t.h - Class stores information from file
#include <string>
class T
{
public:
T();
bool Active();
std::string getA();
void setA(std::string);
private:
std::string a;
};
t.cpp
#include "t.h"
T::T()
{
}
bool T::Active()
{
if(a == "")
{
return false;
}
return true;
}
std::string T::getA()
{
return this->a;
}
void T::setA(std::string newa)
{
this->a = newa;
}
c.h - Class stores T objects and parses file for information
#include "t.h"
#include <QDebug>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
#include <fstream>
class C
{
public:
static C* getInstance();
private:
C();
static C* instance;
static bool init;
std::vector<std::unique_ptr<T>> t_list;
void readLines(const std::string&);
};
c.cpp
#include "c.h"
bool C::init = false;
C* C::instance = nullptr;
C::C()
{
system("echo this is a test command > a.ini");
instance->readLines("a.ini");
}
C* C::getInstance()
{
if(!init)
{
instance = new C;
init = true;
}
return instance;
}
void C::readLines(const std::string &path)
{
T* new_t;
std::ifstream file(path.c_str());
if(!file.is_open())
{
qDebug() << "Unable to open " << path.c_str();
}
std::ofstream o("test.txt");
std::string line;
while(std::getline(file, line))
{
// Split string before searching
std::stringstream ss(line);
std::string seg;
std::vector<std::string> split;
std::string left, right;
// Search patterns
size_t find_a = line.find("a");
size_t del = line.find(':');
if(find_a != std::string::npos)
{
o << "test_Size: " << t_list.size() << std::endl;
if(new_t->Active())
{
T* temp = new_t;
std::unique_ptr<T> move_t(temp);
t_list.push_back(std::move(move_t));
}
o << "test: " << t_list.size() << std::endl;
std::string n;
// Check if previous ahas any null elements
// Split string to find a
n = line.substr(line.find("a "));
n = n.substr(n.find(" ", +2));
new_t->setA(n);
}
else
{
continue;
}
}
// Add last a
T* t = new_t;
std::unique_ptr<T> move_t(t);
//t_list.push_back(std::move(move_t));
o << "a: " << t_list.back().get()->getA() << std::endl;
o << t_list.size() << std::endl;
o.close();
file.close();
}
UPDATE after code change:
I see two things now: One is that new_t in C::readlines is never initialized, so this could break when new_t->Active() is called a bit later in the function. However, I believe that the main problem you're running into is in C::C(), where it says
instance->readLines("a.ini");
At this point in the execution, C::instance is not yet initialized -- you're only just constructing the object that would later be assigned to it. Because of this, this in the readlines call is invalid, and any attempt to access object members will cause UB. This latter problem can be fixed by just calling
readLines("a.ini");
in which case the currently constructed object (that will later be instance) is used for this. I have no idea what you want to happen for the first, though, so all I can say is: If you want to have a vector<unique_ptr<T>>, you will have to create objects of type T with either new T() or (arguably preferrably) std::make_unique<T>() and put them in there.
I'll also say that this is a rather ugly way to implement a singleton in C++. I mean, singletons are never really pretty, but if you're going to do it in C++, the usual way is something like the accepted answer of C++ Singleton design pattern .
Old answer:
The problem (if it is the only one, which I cannot verify because you didn't provide an MCVE) is in the lines
T move_t = new_T;
std::unique_ptr<Adapter> ptr_t(&move_t); // <-- particularly this one
m_ts.push_back(std::move(ptr_t));
You're passing a pointer to a local object into a std::unique_ptr, but the whole purpose of std::unique_ptr is to handle objects allocated with new to avoid memory leaks. Not only will the pointer you pass into it be invalid once the scope surrounding this declaration is left, even if that weren't the case the unique_ptr would attempt to delete an object that's not on the heap at the end of its lifecycle. Both problems cause undefined behavior.
To me, it looks as though you really want to use a std::vector<T> instead of std::vector<std::unique_ptr<T>>, but that's a design issue you'll have to answer yourself.
Answering my own question here. I am trying to call a member variable from within the constructor of the object that holds it, so the vector I am trying to access is not yet instantiated and doesn't exist in memory. That is what causes the Segmentation fault to occur, I am trying to access memory that is not allocated yet, hence any call acting on any member of my C class was causing this issue.
I fixed this problem by adding a public function to the class that then calls the private readLines() function. I call that public function from the object that will take ownership of it, and since this occurs after it has been instantiated, the memory is accessible and the problem disappears.

how does the structure dereference operator work?

I am a java programmer trying to teach myself c++. Please cut me a little slack if I ask simple questions at first.
I would like to understand how the structure dereference operator works. Specifically, can anyone tell me what the following line of code does in explicit terms?
if (elements[i]->test(arga, argb)) {}
test(arga,argb) is a Boolean function in the same class, and elements is a vector of instances of the element class. Here is the code that immediately surrounds the line above, about which I am interested:
for (unsigned i = 0; i < elements.size(); ++i) {
T arga = INFINITY, argb = INFINITY;
//using namespace std;
//std::cout >> elements[i] >> std::endl;
//std::cout >> test(arga, argb) >> std::endl;
if (elements[i]->test(arga, argb)) {
//some code
}
}
It seems that the if line is testing to see whether or not the boolean returned by test(arga,argb) is part of the given instance of the elements class. But when I try to expose the underlying values of elements[i] or test(arga,argb) with the cout lines above, the compiler throws errors until I comment those lines out. In java, I would be able to fiddle around with this until I found values of each that correspond with each other, and then I would understand the line of code. But I do not know how to figure out what this line of code does in C++. Can anyone give me a clear explanation, preferably supported by a link or two to some references online?
elements[i]->test (arga, argb)
If we break down the statement, reading from left-to-right, we will end up with the below:
access the ith element in an array (or array-like) entity named elements
the element accessed (elements[i]) is a pointer to an object
call the member-function named test on elements[i] and pass it two arguments; arga and argb
if we disregard the fact that you wrote std::cout >> instead of std::cout << (the latter is the correct form), we end up with two reasons for your described errors:
your compiler complains about std::cout << element[i] because no suitable overload is found to handle an entity of the type of element[i] and an std::ostream& (which is the underlying type of std::cout).
your compiler complains about std::cout << test (arga, argb) because there is no function in scope named test that takes two arguments corresponding to arga, argv. test, in your snippet, is a member-function that belongs to an entity, it's not callable by its own.
Welcome to C++.
First, the syntax for output is:
cout<<
instead of
cout>>
You are right in guessing that test is a function that returns boolean.Here elements[i] is a pointer pointing to a struct element which has this test function.
To learn C++, you can use these articles that I wrote.Good luck!
Since numerous respondents told me that I need to provide the code before they can answer, I looked deeper in the code, and re-wrote something which tells me that the line:
if (elements[i]->test(arga, argb)) {}
is a test to see whether or not the boolean member function of elements[i] is true.
The c++ program that I wrote to identify the meaning of -> in this context is:
#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
template<typename T>
class Bone
{
public:
std::string myName;
int mySize;
Bone(const std::string &name, const int &size) : myName(name), mySize(size)
{}
bool isBigger(const int &testSize) const
{
if (testSize > mySize) return false;
else return true;
}
};
int main(int argc, char **argv)
{
std::vector<Bone<float> *> bones;
// name, location, size
bones.push_back(new Bone<float>("femur", 10));
bones.push_back(new Bone<float>("ulna", 4));
bones.push_back(new Bone<float>("maxilla", 3));
int testSize = 6;
// test each bone to see if it is bigger than testSize
for (unsigned i = 0; i < bones.size(); ++i) {
if (bones[i]->isBigger(testSize)) {
std::cout << bones[i]->myName; std::cout << " is bigger than testSize! " << std::endl;
}
}
while (!bones.empty()) {
Bone<float> *thisBone = bones.back();
bones.pop_back();
delete thisBone;
}
return 0;
}
Thank you to everyone who led me to figure this out.

How do I print out objects in a vector by overloading the << operator?

Ok so I'm confused about all this operator overloading stuff, the syntax is just weird to me and I'm not that great at programming anyway. So looking around on the internet apparently I think the only way for me to print out objects using cout << is to overload it. So I have a vector of objects and normally if I just had a regular vector of ints or strings then I'd just use an iterator and go through each one and then dereference it to print out whats in it, but I don't think that technique is working for the objects :-/ Here is what I have so far...help!
BarOne.h //my header file
#include <string>
#include <vector>
using namespace std;
class BarOne
{
private:
string name;
string type;
string size;
vector<BarOne> bar; //vector of BarOne objects
vector<BarOne>::iterator it; //iterator for bar
public:
BarOne(); //constructor
void addBottle(string, string, string); //adds a new bottle to bar
void revealSpace();
void printInventory();
friend ostream& operator<<(ostream& os, const BarOne& b);
};
and my implementation looks like:
BarOne.cpp //implementation
#include "BarOne.h"
#include <iostream>
#include <string>
using namespace std;
BarOne::BarOne()
{
//adding 4 default bottles
}
void BarOne::addBottle(string bottleName, string bottleType, string bottleSize)
{
name = bottleName;
type = bottleType;
size = bottleSize;
}
void BarOne::printInventory()
{
for (it = bar.begin(); it != bar.end(); ++it)
{
cout << *it << endl;
}
}
ostream& operator<<(ostream& os, const BarOne& b)
{
os << b.name << "\t\t\t" << b.type << "\t\t\t" << b.size;
return os;
}
so how come when i call printInventory in my main it doesn't do anything? Did I do the overloading wrong? Syntax mistakes?
ok this is the main too:
#include "BarOne.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string Tiqo, Peruvian, Wellington, Smooze;
string vodka;
string rum;
string whiskey;
string small;
string medium;
string large;
//default bottles
vector<BarOne> bar; //vector of BarOne objects
vector<BarOne>::iterator it; //iterator for bar
BarOne Inventory; //BarOne object
Inventory.addBottle(Tiqo, vodka, large);
bar.push_back(Inventory);
Inventory.addBottle(Peruvian, rum, medium);
bar.push_back(Inventory);
Inventory.addBottle(Wellington, vodka, large);
bar.push_back(Inventory);
Inventory.addBottle(Smooze, whiskey, small);
bar.push_back(Inventory);
^^^thats just a piece of it...the rest is just formatting how things are displayed when the program runs and stuff. So ok I'll try and separate the classes like someone suggested tho. AddBottle adds the info for that object in the vector right? it gets the info and then adds it into the variables name, type and size and then its put into the vector "bar". Or no?
You don't show us your main() program. That code, together with your class design which confuses bar contents with the bar is causing the behavior you see.
The operator << is actually OK for outputting data of a bottle. But I'm sure that the BarOne on which it is called has an empty bar vector. Your addBottle() doesn't add anything anywhere (in particular not to the contained bar). Instead it simply sets the properties (data members) of the outer BarOne object.
The origin of that confusion is your class design, where a BarOne apparently is intended to serve both as bottle and as bar (which contains bottles).
I suggest you restart and try with separate Barand Bottleclasses.
BTW: Keeping the iterator you use in local loops as a class member is not a good idea. Sooner or later you will run into reentrancy problems with such approach. Loop iterators should be local variables, preferably scoped to the loop.

std::cout of string not working

I have a class State that has a string data type called moveType. In the implementation of my code, I am calling a setter void setMoveType(string _moveType); and it's implemented with just moveType = _moveType;
When I call my getter string getMoveType() const; on an instance of State and output it to cout, nothing is displayed.
I am couting upon entering the getMoveType() function. The parameter indeed has the correct value, but it appears that it's not getting set at all.
Does anyone have any idea? I feel this is something simple/trivial in c++ that I'm just completely forgetting.
string State::getMoveType() const {
return moveType;
}
void State::setMoveType(string move_type) {
cout << "In setMoveType and param = " << move_type << endl;
moveType = move_type;
}
std::cout << vec_possibleSuccessors[i].getMoveType() << endl; // within loop;
vector<State> vec_possibleSuccessors;
if (_minState.canMoveUp()) {
up = _minState.moveUp();
up.setMoveType("UP");
up.setF(f(up));
vec_possibleSuccessors.push_back(up);
}
In the above code, _minState and up are instances of State. Also, I have made sure that my copy constructor and assignment operator have been modified to include moveType assignments.
There isn't really enough code to know for sure, but I have a guess: Either you actually assigned to a shadowed variable in the "set" function and never set the class attribute at all, or your State object has actually been destroyed and the string becomes empty (since being empty is one possible option when using destroyed memory).
Well not an answer but a short example that works the way you seem to intend this to work:
#include <string>
class State
{
private:
std::string m_moveType;
public:
State() : m_moveType( "unknown" ) {}
std::string getMoveType() const { return m_moveType; }
void setMoveType( const std::string& moveType ) { m_moveType = moveType; }
};
In your main function or were else you need a vector of States you could write this:
#include <iostream>
#include <vector>
#include "State.h"
int main()
{
std::vector< State > states;
for( int i=0; i<10; ++i )
{
State newState;
newState.setMoveType( "state" );
states.push_back( newState );
}
// do whatever you need to do....
std::vector< State >::iterator it;
std::vector< State >::iterator end = states.end();
for( it=states.begin(); it != end; ++it )
std::cout << (*it).getMoveType() << std::endl;
return 0;
}
A few remarks:
passing parameters by value like setMoveType( string s ) is not
adviseable, pass const references instead. Passing by value incurrs a
full copy of the passed object
be careful with includes and namespaces, in doubt take the extra time
to type std::... if you intend to use a feature defined in namespace
std, and never type using namespace std in a header file.
initialize private members to a sensible default and do it in the class
initializer list
I'm not sure on this either, but you appear to be storing this State in a vector. Could you post the code to how you set elements in the vector? Its important to note that you can't update an element in a vector once its inserted (unless you store a pointer to the element). Also depending upon how you call set, there may be problems.