I'm creating a list of structs:
struct task{
int task_id;
bool is_done;
char* buffer;
int length;
} task;
list<task> taskList;
And trying to iterate over the tasks in order to check the is_done status:
for (std::list<task>::const_iterator iterator = taskList.begin(), end = taskList.end(); iterator != end; ++iterator) {
if(iterator->is_done) {
return 1;
} else {
return 2;
}
}
Where am I wrong?
I get: Missing template argument before '->' token
The iterator's operator-> does the dereferencing already. So instead of
if(*iterator->is_done==true)
you need
if(iterator->is_done==true)
is equivalent to
if((*iterator).is_done==true)
which as a sidenote is equivalent to the easier to read
if((*iterator).is_done)
or
if(iterator->is_done)
. Even better, you could also use std::any_of:
#include <algorithm>
....
if (any_of(begin(taskList), end(taskList),
[](task const &t) { return t.is_done; }))
{
return 1;
} else {
return 2;
}
Informal note: There is no need to qualify any_of, begin and end with std::, because taskList is of type std::list<?>, and the C++-compiler will look up those functions in the std-namespace for you already.
Like this
if (iterator->is_done==true){
no need for * and ->.
And not the question you asked but
if (iterator->is_done==true) {
is exactly the same as the easier to understand
if (iterator->is_done) {
Don't compare booleans to true and false, they already are true and false.
Use std::find_if instead:
#include <algorithm>
...
bool isDone(const task &task)
{
return task.is_done;
}
...
return std::find_if(taskList.begin(), taskList.end(), isDone) == taskList.end() ? 2 : 1;
Try this. Note change to task struct and referencing iterator. (I changed name of iterator - to be more concise - but not actually required). I just think looks less confusing.
#include <list>
using namespace std;
struct task{
int task_id;
bool is_done;
char* buffer;
int length;
};
int main() {
std::list<task> taskList;
task task1;
task1.buffer = "qwerty";
task1.is_done = true;
task1.length = 6;
task1.task_id = 1;
taskList.push_back(task1);
for (std::list<task>::const_iterator it = taskList.begin(), end = taskList.end();
it != end; ++it) {
if((*it).is_done==true)
return 1;
else
return 2;
}
return 0;
}
Related
const char *attribute[] =
{"abc","efg","hij","lmn","opq","rst","uvw","Xyz"};
want to find Boolean and location of the "lmn" in the above array.
This example will show you how to get both a bool and an index back.
Demo here : https://onlinegdb.com/vHHJ9QG1M
#include <array>
#include <limits>
#include <algorithm>
#include <iostream>
#include <string_view>
// make a struct to be able to return two (readable) values from function
// I almost never use std::pair it results in hard to read code.
// where you have to check the semantics of first/second over and over again.
struct is_attribute_result_t
{
// conversion to bool so result can be directly used in "if's"
constexpr operator bool() const
{
return is_attribute;
}
bool is_attribute{false};
std::size_t index{std::numeric_limits<std::size_t>::max()};
};
// make a std::array that is usable at compile time
// use string_view because it implements operator== for the whole string (const char* doesn't)
constexpr std::array<std::string_view,8> attributes = {"abc","efg","hij","lmn","opq","rst","uvw","xyz"};
// make a function that can be evaluated at compile time
// so no std::find, just use availability of (constexpr) operator== on string_view
constexpr is_attribute_result_t test_attribute(const std::string_view& attribute)
{
is_attribute_result_t result;
for(std::size_t n = 0; n < attributes.size(); ++n)
{
if(attribute == attributes[n])
{
result.is_attribute = true;
result.index = n;
return result;
}
}
return result;
}
int main()
{
// nice thing is you can now also check at compile time.
static_assert(test_attribute("abc"));
static_assert(test_attribute("abc").index == 0ul);
static_assert(test_attribute("lmn"));
static_assert(test_attribute("lmn").index == 3ul);
static_assert(!test_attribute("123"));
// and ofcourse still use the function at runtime too
if ( auto result = test_attribute("lmn"))
{
std::cout << "lmn is an attribute, and is found at index = " << result.index << "\n";
}
return 0;
}
Lets say we would like to evaluate expressions in a string. Expressions represented by (###) for simplicity in the example. We only count the hashtags in the example for simplicity. Expressions can be nested.
#include <iostream>
#include <string>
std::string expression{ "(###(##)#(###)##)" };
int countHash(std::string::iterator stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
if (*stringIterator == '#')
{
result += 1;
}
else if (*stringIterator == '(')
{
result += countHash(++stringIterator, stringEnd);
}
else if (*stringIterator == ')')
{
return result += countHash(++stringIterator, stringEnd);
}
++stringIterator;
}
return result;
}
int main()
{
std::cout << countHash(expression.begin(), expression.end()) << std::endl;
return 0;
}
Output: 51
Expexted output: 11
So my problem is when I return from the recursive call the iterator is not updated. It is behind. The processing goes through parts of the string multiple times. How should I handle this?
My main goal by the way is to be able to evaluate expressions like this:
std::string expr = "(+1 (+22 3 25) 5 (+44 (*3 2)))";
EXPECT(106== evalExpression(expr.begin(), expr.end()));
Thanks.
EDIT:
I updated my question based on the suggestions in the comments.
#include <string>
#include <iostream>
std::string expression{ "#####-###-##" };
int countHash(std::string::iterator & stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
switch (*stringIterator++)
{
case '#':
result += 1;
break;
case '-':
result += countHash(stringIterator, stringEnd);
break;
default:
// indicate error ?
break;
}
}
return result;
}
int main()
{
std::string::iterator b = expression.begin();
std::cout << countHash(b, expression.end()) << std::endl;
return 0;
}
OK so as I edited my original question, here is a solution for that:
#include <iostream>
#include <string>
std::string expression{ "(###((##)#)(#(#)#)#(#))" };
int countHash(std::string::iterator& stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
if (*stringIterator == '#')
{
result += 1;
}
else if (*stringIterator == '(')
{
result += countHash(++stringIterator, stringEnd);
continue;
}
else if (*stringIterator == ')')
{
++stringIterator;
return result;
}
++stringIterator;
}
return result;
}
int countHash(std::string expression)
{
auto it = expression.begin();
return countHash(it, expression.end());
}
int main()
{
std::cout << countHash(expression) << std::endl;
return 0;
}
Output: 11
So one important thing was that you need to pass the string by reference to avoid processing the same segments of the string multiple times after you return from your recursive calls.
What I also had difficulty with is that you need to do a continue after the recursive call in my while loop. This is because you don't want to increment stringIterator after your return from the recursive call.
You could also do this with the post increment operator and with a switch-case as #bruno did it in his answer. That was the insight for me. If you are not only checking for characters switch-case is not possible though. You could use a do-while loop but I don't like that.
On more important thing was that you need to increment your iterator before returning from the ) branch. That is because that's the end of an expression and if it was a recursive call you want to go on with the expression on the caller side.
One other problem was that you cant pass expression.begin() if your function takes a reference to iterator.
For the
std::string expr = "(+1 (+22 3 25) 5 (+44 (*3 2)))";
expression my solution is available at https://github.com/bencemeszaroshu/expeval/blob/master/expeval/expeval.cpp. I don't like it as it is now but I will try to improve it later. (Happy to hear suggestions.) It is working however. Thanks everyone for your help, I'm marking #bruno answer as accepted because it helped me the most.
Let define a structure parser :
struct parser {
int (*buffer_push_strategy)();
int (*escape_buffer_push_strategy)();
int (*do_callback_strategy)();
};
I have an initialization function :
int parser_init() {
if (some_condition) {
parser->buffer_push_strategy = buffer_push_strategy1;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy1;
parser->do_callback_strategy = do_callback_strategy1;
}
else {
parser->buffer_push_strategy = buffer_push_strategy2;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy2;
parser->do_callback_strategy = do_callback_strategy2;
}
return 0;
}
where the strategy functions are defined somewhere.
Ok, so my interest is to determine which strategy has been used when I write the unit tests. Any idea how to accomplish that?
I saw something on internet about is_pointer function from C++ 11, but I don`t think this would help me.
parser is a variable:
struct parserT {
int (*buffer_push_strategy)();
int (*escape_buffer_push_strategy)();
int (*do_callback_strategy)();
} parser;
If you want to know which the strategy is, you could use:
int strategy= (parser->buffer_push_strategy == buffer_push_strategy1) ? 1 : 2;
Perhaps, you prefer to store the strategy number:
int parser_init() {
if (some_condition) {
parser->buffer_push_strategy = buffer_push_strategy1;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy1;
parser->do_callback_strategy = do_callback_strategy1;
return 1;
}
else {
parser->buffer_push_strategy = buffer_push_strategy2;
parser->escape_buffer_push_strategy = escape_buffer_push_strategy2;
parser->do_callback_strategy = do_callback_strategy2;
return 2;
}
}
Then, you could init the parser as:
const int STRATEGY= parser_init();
You can compare function pointers
if(p.buffer_push_strategy == buffer_push_strategy1)
See https://ideone.com/QQzL1c
I want to remove elements from a std::list with linear complexity (going through each element in the list only once). I need to do so depending on the value of a variable in the stack:
int somevalue= 5;
int count=0;
mylist.remove_if(
[](MyStructure* s)
{
if (s->somefield==somevalue)
{
count++;
return true;
}
else
return false;
});
Of course, this doesn't work - somevalue is a variable in the stack.
I've tried using template functions, only to realize (after illegal operation on bound member function expression) you can't really use them in this situation. I know I need to make a closure somehow, so I've read this question, but I can't use C++0x yet and I failed to adapt the other answer for my usecase, as I don't really understand if there's some magic to operator.
Alternatively, is there some way to remove an element from a list given the current position of an iterator (without going through the whole list again to find the element)?
In terms of the lambda expression (a c++11 feature), you can capture the somevalue by value like this: [somevalue](...) {...}
You need to capture the variable in the sample code:
int somevalue= 5;
mylist.remove_if( [somevalue](MyStructure* s){ s->somefield==somevalue });
If no C++11 could be used you need to make the functor yourself:
// For static constant check
template <int CheckValue>
struct Equal {
operator()(const MyStructure* s) { return s->somefield == CheckValue; }
};
mylist.remove_if(Equal<5>);
..or..
// For dynamic constant check as the sample code
struct Equal {
Equal(int check_value) : m_check_value(check_value) {}
operator()(const MyStructure* s) { return s->somefield == m_check_value; }
private:
int m_check_value;
};
mylist.remove_if(Equal(somevalue));
You must capture somevalue in your lamdba expression to use it:
Example (live here) :
struct MyStructure
{
int somefield;
};
int main(int argc, char** argv) {
std::list<MyStructure> my_list = { { 1 }, { 2 }, { 1 }, { 3 }, { 2 }, { 1 } };
int somevalue = 2;
my_list.remove_if( [somevalue](MyStructure s){ return s.somefield == somevalue; });
// ^^^^^^
// Capture
for(auto& s : my_list)
std::cout << s.somefield << " ";
return 0;
}
Iterate on the elements to identify which one you want to remove. Use erase to remove the identified elements and continue to iterate from the returned iterator.
Something like that:
int somevalue=5;
std::list<MyStructure*> myList;
// ...
std::list<MyStructure*>::iterator it=myList.begin();
while(it!=myList.end())
{
if ((*it)->somefield==somevalue)
{
it = myList.erase(it);
}
else
{
++it;
}
}
I was looking for recursive solution for evaluating expression in Polish prefix notation, didn't find, but i found pseudo code for that and I wanted to translate it to the C++ but it is hard. I wrote BIG LETTERS where I don't know how to do it. Please correct me I am java guy and for me C++ is big mess, but can't help it.
int preEval(stack<string> stos){
string el = "";
if(stos.empty()){
return 0;
}else if(stos.top() IS VALUE){
string el = stos.top();
stos.pop();
return atoi(el.c_str());
}else if(stos.top() IS OPERATOR){
int x = preEval(stos);
int y = preEval(stos);
return x OPERATOR y;
}
return 0;
}
EDIT
When I have expression like / 10 5 Should stack suppose to have elements(from top) / 10 5, or 5 10 / ? Just asking because if I want it in / 10 5 I have to read string somehow backwards.
I think, a better solution would be to split the work into 2 stages: lexing and parsing.
At the lexing stage, you classify each token to see whether it's an operator (+, -, etc.) or a constant, or maybe a variable. Then you pack the parsed entity into a structure containing the type and additional information.
At the parse stage, which is presented by your code, you work not with strings, but with structures. Looking at the structure, you can easily find out its type. (It can be either a field inside the structure or a structure's type if you choose to build a hierarchy of structures derived from a common base.)
Actually, the logic should be the same in both Java and C++.
If you have functions like these:
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <iostream>
#include <stack>
#include <string>
using std::stack;
using std::string;
using std::cerr;
enum Operator {
operator_none,
operator_plus,
operator_minus
};
Operator tokenOperator(const string &token)
{
if (token=="+") return operator_plus;
if (token=="-") return operator_minus;
return operator_none;
}
int applyOperator(Operator op,int x,int y)
{
switch (op) {
case operator_plus: return x+y;
case operator_minus: return x-y;
case operator_none:
break;
}
assert(false);
return 0;
}
bool isValue(const string &token,int &output_value)
{
char *end = 0;
errno=0;
output_value = strtol(token.c_str(),&end,10);
if (errno!=0) return false;
return *end=='\0';
}
bool isOperator(const string &token,Operator &output_operator)
{
output_operator = tokenOperator(token);
return output_operator!=operator_none;
}
Then preEval can be implemented like this:
int preEval(stack<string> &stos)
{
if (stos.empty()) return 0;
string el = stos.top();
stos.pop();
int value = 0;
Operator op = operator_none;
if (isValue(el,value)) return value;
if (isOperator(el,op)) {
int x = preEval(stos);
int y = preEval(stos);
return applyOperator(op,x,y);
}
return 0;
}
#include <string>
#include <map>
using namespace std;
bool is_value(string s) {
return s.find_first_not_of("0123456789") == string::npos;
}
int do_add(int x, int y) {
return x + y;
}
int do_subtract(int x, int y) {
return x - y;
}
// etc.
typedef int (*binary_op)(int, int); // Give this function pointer type a nice name
map<string, binary_op> ops;
// Somewhere before the preEval() is ever called
ops["+"] = do_add;
ops["-"] = do_subtract; // etc.
binary_op lookup_op(string s) {
map<string, binary_op>::const_iterator it = ops.find(s);
if (it != ops.end()) {
return *it;
} else {
return NULL;
}
}
Now, instead of separately testing whether the token is an operator and later performing that operator, use a single function call to get a pointer to the operator function that needs to be called (if the token is an operator) or NULL otherwise. I.e.:
}else if(stos.top() IS OPERATOR){
int x = preEval(stos);
int y = preEval(stos);
return x OPERATOR y;
}
becomes
} else {
binary_op op = lookup_op(stos.top());
if (binary_op != NULL) {
stos.pop(); // This fixes the bug I mentioned in my top comment
int x = preEval(stos);
int y = preEval(stos);
return op(x, y);
} else {
syntax_error();
}
}