How to use it->empty() in an iterator - c++

I want to use an iterator as a condition of a for loop, but when I define it, it->empty() always reports an error. I don’t know where the error is. When I change it to (*it).empty() It will also report an error later
The error is: the expression must contain a pointer type to the class, but it has type "char *"
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
string s("some string");
for (auto it = s.begin(); it != s.end() && !it->empty(); it++)
{
cout<< *it <<endl;
}
}

The problem is that you are trying to access a member function called empty through a non-class type object(a char type object in this case). You can change your code to look like below:
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
std::vector<std::string> vec = {"some", "string", "is", "this"};
for (auto it = vec.begin(); it != vec.end() && !it->empty(); it++)
{
cout<< *it <<endl;
}
}
The above code works because this time we are using/calling the member function empty through a class type object(a std::string object in this modified example).
Also if you only wanted to know why you're having this error then i think the comments and my answer, answer that. If you have any other/further question then you can edit your question to add that.

Related

C++ Vector and Functions - Cannot get the program to work. Need help,

Hey guys? I'm new to the whole C++ Standard Library thing, but for the devil of me, I cannot figure out why this program is not giving me the output I hope.
#include <iostream>
#include <vector>
#include <iterator>
/*
create_vec should initialise my vector and return an iterator pointing to
it.
*/
template <typename s>
typename std::vector<s>::iterator create_vec(s var) {
std::vector<s> tempVec;
tempVec.push_back(var);
auto itr = tempVec.begin();
return itr;
}
int main() {
std::vector<int>::iterator itr = create_vec<int>(148);
std::cout << *itr << "was passed." << std::endl;
return 0;
}
O/P : 0 was passed to the create vec function
p.s ignore all the std's. I want to know at each moment where i got each type, function etc.
The variable tempVec is local inside the create_vec function. When the function returns the vector object is destructed, leaving you with an iterator to something which doesn't exist any more. That leads to undefined behavior when you try to use the iterator.
Isn't the purpose of the create_vec function to return the vector instead? The name of the function suggests it should do so.

C++ STL vector init

I am just wondering how I could solve this problem.
I have a
vector<char> vstr;
definition in the class Program.
Then in the class constructor I want to init this vector with an array:
char arrayOfChars[] = {'a', 'b', 'c'};
this.vstr = new vector<string>(arrayOfChars, arrayOfChars + sizeof(arrayOfChars)/sizeof(arrayOfChar[0]));
The build gives me a bug:
error: request for member 'vstr' int 'this', which is of non-class type 'Program *const' .
Could you give me a simple solution for this error?
I'm not an expert in C++ but I see at least two problems:
You are trying to initialise an object with a pointer. Don't use new key word.
What is more this pointer points to vector of strings not chars, so replace vector<string> with vector<char>.
As melak47 says in his comment this.vstr is also incorrect because this is a pointer and therefore should be replaced with this->vstr or simply vstr
Once you make all the three corrections it should compile
I think that piece of code is what you want.
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
class Program {
vector<char> vstr;
public:
Program(const char* data)
{
string s(data);
std::copy(s.begin(), s.end(), std::back_inserter(vstr));
}
void PrintData()
{
for (auto it = vstr.begin(); it != vstr.end(); it++)
{
std::cout << (*it);
}
}
};
int main()
{
Program p("simple data");
p.PrintData();
}

Erase function wrong call

I am writing this code
string largestNumber(const vector<int> &A) {
{
//Doing something
}
result.append(to_string(A[maxindex]));
A.erase(A.begin()+maxindex);
}
cout << result;
}
Now in this I am using the erase function correctly. Passing the iterator from the start and adding index value to it.So what am I doing wrong here?
The error comes
no matching member function for call to 'erase'
I have included the vector header as
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
"Now in this I am using the erase function correctly."
No you don't.
According the declaration described here
Type requirements
-T must meet the requirements of MoveAssignable.
you cannot modify a const referenced std::vector, erase() requires a non const reference, so what's actually unclear about the compiler error message?
You have to declare your function that it receives a non const reference parameter:
string largestNumber( /* const */ vector<int> &A) {
// ^^^^^ omit this
or make it eligible for moving
string largestNumber( vector<int> &&A) {

C++ Generic Swap Function

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.

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.