Please explain with examples when to use std::logical_not and when std::not1!
According to documentation, the former is a "unary function object class" while the latter "constructs a unary function object". So at the end of the day both construct a unary function object, don't they?
Both are functors (a class with an operator()), but differ slightly on what they negate:
std::logical_not<T>::operator() returnsT::operator!(). Semantically, it sees T as a value and negates it.
std::not1<T>::operator() returns !(T::operator()(T::argument_type&)). Semantically, it sees T as a predicate and negates it.
std::not1<T> is a generalization of std::logical_not for more complex use case.
Please explain with examples when to use std::logical_not and when std::not1
Use std::logical_not whenever you can. Use std::not1 whenever your first option is out. The example on en.cppreference.com gives a case where std::not1 is necessary:
#include <algorithm>
#include <numeric>
#include <iterator>
#include <functional>
#include <iostream>
#include <vector>
struct LessThan7 : std::unary_function<int, bool>
{
bool operator()(int i) const { return i < 7; }
};
int main()
{
std::vector<int> v(10);
std::iota(begin(v), end(v), 0);
std::cout << std::count_if(begin(v), end(v), std::not1(LessThan7())) << "\n";
//same as above, but use a lambda function
std::function<int(int)> less_than_9 = [](int x){ return x < 9; };
std::cout << std::count_if(begin(v), end(v), std::not1(less_than_9)) << "\n";
}
Related
I wanted a simple function that takes a collection of strings and appends them and returns one string which is each string item appended together. I thought std::accumulate was the way to go but interested to hear if this code could be improved.
Is there a simpler append type function that can be used here instead of the lambda?
Is this overly complicated and best achieved by some other code?
#include <string>
#include <vector>
#include <iostream>
#include <numeric>
std::string concatenate(std::vector<std::string> strings)
{
return std::accumulate(strings.begin(), strings.end(), std::string(""), [](std::string s1, std::string s2) { return s1 + s2; });
}
int main() {
std::vector<std::string> vec2{ "aaa","bbb","ccc","ddd","eee","fff" };
std::cout << concatenate(vec2) << std::endl;
}
Yes, you can omit the lambda entirely (or use std::plus<>{}).
Also the "" can be removed from std::string(""), or the whole third argument can be removed if you switch to std::reduce:
std::reduce(strings.begin(), strings.end());
Also concatenate should take the vector by a const reference, or even better a std::span<const std::string> (by value).
Also libfmt can be used for this:
fmt::format("{}", fmt::join(strings, ""));
It can be simplified with C++17 fold expression, there is no an intermediate or a temporary collection needed.
#include <string>
#include <iostream>
template<typename ...S>
std::string concatenate(S&&... strings) {
using namespace std::string_literals;
return (""s + ... + strings);
}
int main() {
std::cout << concatenate("aaa","bbb","ccc","ddd","eee","fff") << std::endl;
}
I noticed that I can seemingly get the same logic(copy elements matching some predicate into vector) both using ranges::copy_if and also using vector constructor taking 2 iterators(by providing it with filter_view .begin() and .end()).
#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
#include <utility>
#include <fmt/ranges.h>
const std::vector<int> vals{1,2,3,47,8472};
const auto filter_pred = [](const int i){return i%2==0;};
void fna(){
std::vector<int> result;
std::ranges::copy_if(vals, std::back_inserter(result), filter_pred);
std::cout << fmt::format("{}", result) << std::endl;
}
void fn1(){
auto filtered = vals | std::views::filter(filter_pred);
std::vector<int> result {filtered.begin(), filtered.end()};
std::cout << fmt::format("{}", result) << std::endl;
}
std::vector<int> fna_val(){
std::vector<int> result;
std::ranges::copy_if(vals, std::back_inserter(result), filter_pred);
return result;
}
std::vector<int> fn1_val(){
auto filtered = vals | std::views::filter(filter_pred);
return {filtered.begin(), filtered.end()};
}
int main(){
fna();
fn1();
std::cout << fmt::format("{}", fna_val()) << std::endl;
std::cout << fmt::format("{}", fn1_val()) << std::endl;
}
Is there a reason to prefer one over other?
What I can think of:
it is unlikely that either is more efficient, since I doubt that any real optimizations can be done since because _if in copy_if means destination size is unknown.
compile speed: copy_if could be faster to compile since it does not require <ranges> header, but did not benchmark
const all the things: copy_if requires mutable destination container, range construction does not
verbosity: when return type of function is known we do not need to spell out the std::vector in body, {} works. Would be nice if vector understood ranges so we would not have to use .begin() .end(), but it does not.
I would like to create and hold on to an iterator_range. The range is constructed based on a predicate (for this example, I look for even numbers).
I can do this, but it seems I must make a copy elements from the underlying vector that is being iterated.
Please look for the comments marked ">>>" in the sample below.
Is there a way to create the iterator_range and NOT have to create a duplicate of entries from the original vector?
I looked, and have not seen, an answer to this particular situation.
#include <vector>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
using namespace std;
using namespace boost;
typedef boost::iterator_range<vector<int>::iterator> int_range;
template< class Range, class Pred >
boost::iterator_range< boost::filter_iterator< Pred, typename boost::range_iterator<Range>::type > >
make_filter_range( Range& rng, Pred pred ) {
return boost::make_iterator_range(
boost::make_filter_iterator(pred, boost::begin(rng), boost::end(rng)),
boost::make_filter_iterator(pred, boost::end(rng), boost::end(rng)) );
}
// This is the predicate evaluation function.
bool IsEvenFilter(int val) { return val % 2 == 0; }
void TestMakeIteratorRange()
{
std::vector<int> vals;
vals.push_back(1);
vals.push_back(4);
vals.push_back(7);
vals.push_back(11);
vals.push_back(16);
vals.push_back(19);
vals.push_back(28);
//>>> The following int_range line does not compile. Why?
//>>> How can I return an int_range?
//>>> int_range intRange = make_filter_range( vals, boost::bind(&IsEvenFilter, _1));
//>>> The following WILL work, but it forces a second copy of elements from vals.
std::vector<int> v2 = boost::copy_range< std::vector<int> >(
make_filter_range( vals, boost::bind(&IsEvenFilter, _1)));
int_range intRange = int_range(v2);
// Dump out contents
BOOST_FOREACH(int &val, intRange)
{
cout << " " << val;
}
cout << endl;
}
void main()
{
TestMakeIteratorRange();
}
int_range intRange = make_filter_range( vals, boost::bind(&IsEvenFilter, _1));
You have to store the type returned by make_filter_range. Which is not int_range.
This is incidentally why auto exists (in C++11); so that you don't have to type that return value if you want to store what the function returns. If you don't have access to C++11 auto, use BOOST_AUTO instead.
If you can't use that for some reason, you can also use any_range. Which, as the name suggests, can store any range for a specific type.
Also, consider using the proper Boost range-adapters, like boost::adaptors::filtered instead of make_filter_iterator.
Is there a more straight-forward way to do this?
for_each(v_Numbers.begin(), v_Numbers.end(), bind1st(operator<<, cout));
Without an explicit for loop, if possible.
EDIT:
How to do this for std::cin with a std::vector if possible? (How to read n elements only)?
You could achieve this using std::copy into a std::ostream_iterator:
std::vector<int> v_Numbers; // suppose this is the type
// put numbers in
std::copy(v_Numbers.begin(), v_Numbers.end(),
std::ostream_iterator<int>(std::cout));
It would be even nicer if you add some suffix:
std::copy(v_Numbers.begin(), v_Numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"));
This assumes that your container is a vector<int>, so you will have to replace that part with the appropriate type.
Edit regarding reading input:
Conversely, you can copy from a range of std::istream_iterator into a vector using std::back_inserter:
std::vector<int> v_Numbers;
std::copy(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(),
std::back_inserter(v_Numbers));
If you want to read n elements only, look at this question.
Another option — Boost.Lambda.
for_each(v.begin(), v.end(), cout << boost::lambda::_1);
Yep, but you must use std::copy algorithm:
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> a;
// fill a...
std::copy(a.begin(), a.end(), std::ostream_iterator<int>(std::cout));
}
yup, using lambda expression (C++ 11) we can inline printing of each element of a STL container to cout.
#include <iostream> // cout
#include <vector> // vector
#include <algorithm> // for_each
#include <iterator> // istream_iterator
using namespace std;
int main()
{
std::vector<int> v(10,2);
std::for_each(v.begin(), v.end(), [](int i)->void {std::cout << i <<endl;});
return 0;
}
For reading "n" values from cin to vector,
int main()
{
std::vector<int> v;
int elementsToRead;
cin>>elementsToRead; // Number of elements to copy
// Reading from istream
std::istream_iterator<int> ii2(std::cin);
std::copy_n(ii2, elementsToRead, std::back_inserter(v));
// printing updated vector
std::for_each(v.begin(), v.end(), [](int i)->void {cout << i <<endl;});
return 0;
}
(or) by using Lambda expression
std::for_each(std::istream_iterator<int>(cin),std::istream_iterator<int>(),[&v](int i)->void { v.push_back(i);});
To know more about Lambda expression # What is a lambda expression in C++11?
Not always appropriate in corporate code, but for the sake of enumerating options - if you really find other for_each / std::copy etc. solutions too verbose, you could write:
std::ostream& operator(std::ostream& os, const std::vector<My_Type>& v)
{
// pick one of the other implementations for here...
std::copy(std::istream_iterator<My_Type>(os), std::istream_iterator<My_Type>(),
std::back_inserter(v_Numbers));
}
It's much nicer if you're well-mannered (;-p) enough to only overload your specific instantiation of vector (which requires My_Type be more than a typedef to say int, though it's not hard to create a templated class to create new types wrapping an arbitrary type). Otherwise, if someone else does the same elsewhere in your translation unit, the streaming could become ambiguous.
I know the copy with the iterator is the optimal solution, but just to answer with for_each.
You could do:
#include <vector>
#include <algorithm>
#include <locale>
int main() {
using namespace std;
locale::global(locale(""));
wcout::imbue(locale());
vector<int> vec{1000,2000,3000,4000,5000};
for_each(vec.begin(), vec.end(), [](auto &x){wcout << x << endl;});
return 0;
}
But, for me, it's REALLY much more readable the simple for ...
#include <vector>
#include <locale>
int main() {
using namespace std;
locale::global(locale(""));
wcout::imbue(locale());
vector<int> vec{1000,2000,3000,4000,5000};
for(auto &v: vec) {
wcout << v << endl;
}
return 0;
}
The following code causes cl.exe to crash (MS VS2005).
I am trying to use boost bind to create a function to a calls a method of myclass:
#include "stdafx.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
class myclass {
public:
void fun1() { printf("fun1()\n"); }
void fun2(int i) { printf("fun2(%d)\n", i); }
void testit() {
boost::function<void ()> f1( boost::bind( &myclass::fun1, this ) );
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this ) ); //fails
f1();
f2(111);
}
};
int main(int argc, char* argv[]) {
myclass mc;
mc.testit();
return 0;
}
What am I doing wrong?
Use the following instead:
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this, _1 ) );
This forwards the first parameter passed to the function object to the function using place-holders - you have to tell Boost.Bind how to handle the parameters. With your expression it would try to interpret it as a member function taking no arguments.
See e.g. here or here for common usage patterns.
Note that VC8s cl.exe regularly crashes on Boost.Bind misuses - if in doubt use a test-case with gcc and you will probably get good hints like the template parameters Bind-internals were instantiated with if you read through the output.
Boost.Bind is a library that simplifies and generalizes capabilities that originally required std::bind1st() and std::bind2nd()
Example 1.1: std::for_each() with a compatible function
#include <vector>
#include <algorithm>
#include <iostream>
void print(int i)
{
std::cout << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), print);
}
The third parameter of std::for_each() is a function or function object that expects a sole parameter. In Example 1.1, std::for_each() passes the numbers in the container v as sole parameters, one after another, to print().
If you need to pass in a function whose signature doesn’t meet the requirements of an algorithm, it gets more difficult. For example, if you want print() to accept an output stream as an additional parameter, you can no longer use it as is with std::for_each().
Example 1.2. std::for_each() with std::bind1st()
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
class print : public std::binary_function<std::ostream*, int, void>
{
public:
void operator()(std::ostream *os, int i) const
{
*os << i << '\n';
}
};
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), std::bind1st(print{}, &std::cout));
}
Like Example 1.1, Example 1.2 writes all numbers in v to standard output. However, this time, the output stream is passed to print() as a parameter. To do this, the function print() is defined as a function object derived from std::binary_function.
With Boost.Bind, you don’t need to transform print() from a function to a function object. Instead, you use the function template boost::bind(), which is defined in boost/bind.hpp.
Example 1.3: std::for_each() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
void print(std::ostream *os, int i)
{
*os << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), boost::bind(print, &std::cout, _1));
}
Example 1.3 uses print() as a function, not as a function object. Because print() expects two parameters, the function can’t be passed directly to std::for_each(). Instead, boost::bind() is passed to std::for_each() and print() is passed as the first parameter to boost::bind().
Since print() expects two parameters, those two parameters must also be passed to boost::bind(). They are a pointer to std::cout and _1.
_1 is a placeholder. Boost.Bind defines placeholders from _1 to _9. These placeholders tell boost::bind() to return a function object that expects as many parameters as the placeholder with the greatest number. If, as in Example 1.3, only the placeholder _1 is used, boost::bind() returns a unary function object – a function object that expects a sole parameter. This is required in this case since std::for_each() passes only one parameter.
std::for_each() calls a unary function object. The value passed to the function object – a number from the container v – takes the position of the placeholder _1. boost::bind() takes the number and the pointer to std::cout and forwards them to print().
Please note that boost::bind(), like std::bind1st() and std::bind2nd(), takes parameters by value. To prevent the calling program from trying to copy std::cout, print() expects a pointer to a stream. Boost.Ref provides a function which allows you to pass a parameter by reference.
Example 1.4 illustrates how to define a binary function object with boost::bind(). It uses the algorithm std::sort(), which expects a binary function as its third parameter.
Example 1.4. std::sort() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2));
for (int i : v)
std::cout << i << '\n';
}
In Example 1.4, a binary function object is created because the placeholder _2 is used. The algorithm std::sort() calls this binary function object with two values from the container v and evaluates the return value to sort the container. The function compare() is defined to sort v in descending order.
Since compare() is a binary function, it can be passed to std::sort() directly. However, it can still make sense to use boost::bind() because it lets you change the order of the parameters. For example, you can use boost::bind() if you want to sort the container in ascending order but don’t want to change compare()
Example 1.5. std::sort() with boost::bind() and changed order of placeholders
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));
for (int i : v)
std::cout << i << '\n';
}
The following works for me.
class test_component
{
private:
void on_wait_complete(const int i);
};
void test_component::on_wait_complete (const int i)
{
cout << "on_wait_complete was called" << endl;
return;
}
int main()
{
// timerPtr_ is a variable declared in class test_component.
timerPtr_->async_wait(boost::bind(&test_component::on_wait_complete, this, _1));
}