How can I combine several functors to generate a isOdd functor?
equal_to
modulus
bind2nd
...
int nums[] = {0, 1, 2, 3, 4};
vector<int> v1(nums, nums+5), v2;
remove_copy_if(v1.begin(), v1.end(), back_inserter(v2), isOdd);
v2 => {0, 2, 4}
Using just the primitives provided in the standard libraries, this is actually surprisingly difficult because the binders provided by bind1st and bind2nd don't allow you to compose functions. In this particular case, you're trying to check if
x % 2 == 1
Which, if you consider how the <functional> primitives work, is equivalent to
equal_to(modulus(x, 2), 1)
The problem is that the components in <functional> don't allow you to pass the output of one function as the input to another function very easily. Instead, you'll have to rely on some other technique. In this case, you could cheat by using two successive applications of not1:
not1(not1(bind2nd(modulus<int>(), 2)))
This works because it's equivalent to
!!(x % 2)
If x is even, then this is !!0, which is false, and if x is odd this is !!1, which is true. The reason for the double-filtering through not1 is to ensure that the result has type bool rather than int, since
bind2nd(modulus<int>(), 2)
is a function that produces an int rather than the bool you want.
isOdd can be defined as:
bind2nd(modulus<int>(),2)
Related
In python, one can easily determine whether arr1 is identical to arr2, for example:
[1,2,3] == [1,2,3]
{1,2,3} == {3,1,2}
(1,2,3) == (1,2,3)
How do you do this in C++?
//#include <bits/stdc++.h>
using namespace std;
int main()
{
// if ({1, 2}== {1, 2})
// cout<<" {1, 2}== {1, 2}";
if ((1, 2)== (2, 2))
cout<<" (1, 2)== (1, 2) equal";
}
if ({1, 2}== {1, 2}) cout<<" {1, 2}== {1, 2}"; throws an error error: expected primary-expression before ‘{’ token, however, if ((1, 2)== (2, 2)) cout<<" (1, 2)== (1, 2) equal"; gives unexpected result, it thinks (1, 2) and (2, 2) are the same.
Do I have to convert list to vector do the comparison in C++, like below?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
if (vector<int>({1, 2})== vector<int>({1, 2}))
cout<<" vector<int>({1, 2})== vector<int>({1, 2}";
}
So what are the data type of (1,2) and {1,2} in C++?
So what are the data type of (1,2) and {1,2} in c++?
(1,2) is an expression that uses the comma operator. The type of this expression is int.
{1,2} is an adventure into the shadowy parts of C++. This construct itself is syntactically a braced initialization list, and it is not a formal type in of itself, of any kind. This always creates a bunch of sad faces whenever one wants to employ the services of forwarding references since braced initialization lists are not formal types, and cannot be squeezed into a forwarding reference.
But all hope is not lost. When used in the context shown here, before too much time elapses this construct quickly becomes a std::initializer_list, which is a very real type. And then, in the shown code, this gets passed to std::vector's overloaded constructor, which takes a std::initializer_list as its parameter.
In python, one can easily determine whether arr1 is identical to arr2,
for example:
[1,2,3] == [1,2,3]
In Python the square brackets are enough to denote a list. In C++, which a statically typed language, you can't do this. You have to declare the arrays or vectors using their types:
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {1, 2, 3};
As explained in the other answers, on it's own {1, 2, 3} is a braced initialization list, not an array or vector. In C++, arrays and vectors do not have value semantics. You can't compare them like you would two integers using ==. Instead you would have to use a function, such as std::equal, from the standard library to compare the two:
std::equal(std::begin(vec1), std::end(vec1), std::begin(vec2), std::end(vec2))
which internally compares each element in the two vectors one by one. Of course, this is more long winded than in Python but under the hood Python is doing the same thing.
Alternatively, you can use std::array, which is a container that encapsulates fixed size arrays and that does have an operator ==:
std::array<int, 3>{1,2,3} == std::array<int, 3>{1,2,3}
For sets:
{1,2,3} == {3,1,2}
and tuples:
(1,2,3) == (1,2,3)
you can use the == operator like so:
std::set<int>{ 1, 2, 3 } == std::set<int>{3, 1, 2}
std::make_tuple( 1, 2, 3 ) == std::make_tuple(3, 1, 2)
but you have to explicitly create the sets and tuples first unlike Python, which infers from the brackets what you want to create.
Demo
So what are the data type of (1,2) and {1,2} in c++?
{1,2} is an initializer list, you can't use it in a comparison like that but you can assign it, i.e:
std::initializer_list<int> init = {1, 2};
You can access the data using iterators, init.begin() will give you a pointer to the first element and you can go on from there, if you specify a type, it will give you more functionality, for example:
std::vector a = {1, 2};
Here you have a vector of int with two elements 1 and 2.
(1, 2) == (2, 2) is really nothing, the element on the left of the comma will be discarded, it's as if you have 2 == 2.
Do I have to convert list to vector do the comparison in C++, like below?
AFAICT, yes, a type must be involved for a proper comparison to take place.
If you must use arrays and you're sure the arrays will have the same number of elements you can use is_permutation to assert if the arrays have the same elements in a different order:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v1 {1, 2, 3};
std::vector<int> v2 {3, 1, 2};
if(std::is_permutation(v1.begin(), v1.end(), v2.begin())){
std::cout << "v1 == v2";
}
}
Alternatively you can use std::sort and then perform the comparison, provided you use an STL container, like a std::vector or an std::array for which overloads exist for the == operator.
If you are able to use other kinds of collections, my advice would be to use an std::set which will compare true whatever the order of insertion may be:
#include <iostream>
#include <set>
int main() {
std::set<int> s1 {1, 2, 3};
std::set<int> s2 {3, 1, 2};
if(s1 == s2){
std::cout << "s1 == s2";
}
}
You can access the full container library and its details here then you can choose the one which is more suited to your needs.
I am trying to implement a bottom up approach function to the rod cutting problem and I need to use this particular pseudo-code from the CLRS textbook. In it there two functions and one calls the other in this fashion
(r,s) = EXTENDED-BOTTOM-UP-CUT-ROD(p,n)
Where r and s are two different arrays. The function also returns two arrays. I am currently using C++ and I've tried things such as
(r,s)=function(p,n);
[r,s]=function(p,n);
{r,s}=function(p,n);
//return statements follow similar attempts
return (r,s);
return {r,s};
return [r,s];
All these typically resulted in errors or incorrect outputs. Perhaps I shouldn't be using basic arrays for this implementation?
You can use tuples and "structured binding" in C++17 to return multiple values efficiently as below:
#include <tuple>
#invlude <vector>
std::tuple<std::vector<int>,std::vector<int>> func_that_returns_two_vectors() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
return {std::move(v1), std::move(v2)};
}
int main() {
auto [v1, v2] = func_that_returns_two_vectors();
return 0;
}
To do something similar pre-C++17 you can use std::tie.
As we know that in c++20 pipe operator | stands for function composition but here in below code we are passing one container and one algorithm so how is it working and how we are able to pass different container types to same function?
int main()
{
std::vector<int> vnumbers = {1, 2, 3, 4, 5, 6};
std::list<int> lnumbers = {6, 5, 4, 3, 2, 1};
auto vresults = vnumbers | std::views::filter([](int n){ return n % 3 == 0; });
auto lresults = lnumbers | std::views::filter([](int n){ return n % 3 == 0; });
for (auto e:vresults)
{
std::cout<<"V:"<<e<<std::endl;
}
for (auto e:lresults)
{
std::cout<<"L:"<<e<<std::endl;
}
}
As we know that in c++20 pipe operator | stands for function composition but here in below code we are passing one container and one algorithm so how is it working
Saying that | stands for function composition is a bit inaccurate, exactly for the reason you mention in your question: function composition allows composing functions together, in line with the mathematical definition.
On the other hand, when we don't want to be too pedantic, we can accept that composing functions means "using them with a nice syntax that allows piping a single flow of data through many of them". That's kind of what Range-v3 and <ranges> allows. Writing this
auto out = in | filter(f) | tranform(g) | take(n) | drop(m);
means the same as this (modulo I've not tested, probably the arguments go the other way around, I don't rememeber, as I always use the | syntax)
auto out = drop(take(transform(filter(in, f), g), n), m);
which means that you are applying to in the composition of 4 functions. BUT those 4 functions are not filter, transform, take, and drop, but rather those 4 functions with their second argument bound to f, g, n, and m respectively.
Boost.Hana does offer a function composition function called boost::hana::compose.
Notice that functions with their second argument bound to refers to what is known as "partial function application", and Boost.Hana also gives you that, via boost::hana::partial and boost::hana::reverse_partial.
how we are able to pass different container types to same function?
Well, we are in C++ and we have templates, so passing objects of different types to the same "function" (well, function template) shouldn't scare us. In the context of ranges, all those functions/function objects filter, transform, and so on, expect a range, i.e. something on which begin and end can be called, so both std::vector and std::list comply with the requirement.
I wrote a vector type using the Clang SIMD vector extensions. It works well, except when I need to check if two vectors are equal. The == operator doesn't seem to be defined correctly for Clang's vector types. Attempting to compare two vectors with == bizarrely seems to evaluate to a third vector of the same type as the two being compared, instead of a bool. I find this odd, since applying other operations like + or - compiles with no trouble, and outputs the expected results. Here's my code, compiled with Clang 3.5 (Xcode):
// in vect.h
template <typename NumericType>
using vec2 = NumericType __attribute__((ext_vector_type(2))) ;
//in main.cpp
#include "vect.h"
int main(int argc, const char ** argv) {
vec2<int> v0 {0, 1} ;
vec2<int> v1 {0, 1} ;
vec2<int> sumVs = v0 + v1 ; //OK: evaluates to {0, 2} when run
bool equal = (v0 == v1) ; /* Compiler error with message: "Cannot initialize
a variable of type 'bool' with an rvalue of type 'int __attribute__((ext_vector_type(2)))'" */
return 0;
}
Is there any way to enable using operator == with Clang's vector types, or any other workaround to this problem? Since they're considered primitive and not class types, I can't overload a comparison operator myself, and writing a global equals() function seems kludgy and inelegant.
Update: Or if no one has the solution I'm looking for, perhaps someone could explain the default behavior of the == operator when comparing two SIMD vectors?
Update #2: Hurkyl suggested == on two vectors does a vectorized comparison. I updated my code to test that possibility:
template <typename NumericType>
using vec3 = NumericType __attribute__((ext_vector_type(3))) ;
int main(int argc, const char ** argv) {
vec3<int> v0 {1, 2, 3} ;
vec3<int> v1 {3, 2, 1} ;
auto compareVs = (v0 == v1) ;
return 0;
}
LLDB reports the value of compareVs as {0, -1, 0}, which seems almost right if that's what's happening, but it seems weird that true would be -1, and false be 0.
Update #3: Ok, so thanks to the feedback I've gotten, I now have a better understanding of how relational and comparison operators are applied to vectors. But my basic problem remains the same. I need a simple and elegant way to check, for any two SIMD-type vectors v1 and v2, whether they are equivalent. In other words, I need to be able to check that for every index i in v1 and v2, v1[i] == v2[i], expressed as a single boolean value (that is, not as an vector/array of bool). If the only answer really is a function like:
template <typename NumericType>
bool equals(vec2<NumericType> v1, vec2<NumericType> v2) ...
... then I'll accept that. But I'm hoping someone can suggest something less clumsy.
If instead of using the compiler-specific language extensions you use the instrinsics (as provided, for example, in xmmintrin.h), then you can use
_mm_movemask_ps(__m128) and its relatives. For example
__m128 a,b;
/* some code to fill a,b with integer elements */
bool a_equals_b = 15 == _mm_movemask_ps(_mm_cmpeq_epi32(a,b));
This code works as follows. First, _mm_cmpeq_ps(a,b) generates another __m128 with each of the four elements to be either all bits 0 or all bits 1 – I presume operator== for the compiler-generated vector extensions calls exactly this intrinsic). Next, int _mm_movemask_ps(__m128) returns an integer with the kth bit set to the signbit of the kth element of its argument. Thus, if a==b for all elements, then _mm_movemask_ps(_mm_cmpeq_epi32(a,b)) returns 1|2|4|8=15.
I don't know the compiler-supported language extensions, but if you can obtain the underlying __m128 (for 128 bit wide vectors), then you can use this approach (possibly only the call to _mm_movemask_ps()).
Using the bitwise-complement of false as a true value isn't that unusual (see BASIC, for example).
It's particularly useful in vector arithmetic if you want to use it to implement to implement a branch-free ternary operator:
r = (a == c)? b: d
becomes
selector = (a == c)
r = (b & selector) | (d & ~selector)
I want to be able to write in C++ something similar to the following Python code:
if x in [1, 2, 3, 5] ...
to test whether an element is contained in a set of hard-coded values, defined in-place. Like this:
if (in(x, {1, 2, 3, 5})) ...
Here is the possible implementation of the in function:
template<class T>
bool in(const T& x, std::initializer_list<T> c)
{
return std::find(c.begin(), c.end(), x) != c.end();
}
My question is: do I really have to write this function by myself? Are there any default implementations over there? Maybe in boost? I checked boost::contains, but it works only with strings.
If you have access to c++20 you can use set's contains which returns a bool allowing you to do:
if(set{ 4, 8, 15, 16, 23, 42 }.contains(x))
Live Example
Otherwise, with just c++11 you can still use set's count which only returns 1 or 0 allowing you to do something like:
if(set<int>{ 4, 8, 15, 16, 23, 42 }.count(x) > 0U)
Live Example
Keep in mind that magic numbers can be confusing for your audience (and cause 5 seasons of Lost.)
I'd recommend declaring your numbers as a const initializer_list<int> and giving them a meaningful name:
const auto finalCandidates{ 4, 8, 15, 16, 23, 42 };
if(cend(finalCandidates) != find(cbegin(finalCandidates), cend(finalCandidates), x))
boost::algorithm::contains doesn't only work on strings, it works on any range, i.e. a sequence that can yield a begin and end iterator. To find a single value use it as follows:
auto l = {1,2,3,4};
auto l1 = {2}; // thing you want to find
if(boost::algorithm::contains(l, l1)) { ... }
You can perform your search using the standard library only, but doing so is quite a bit more verbose. A couple of options are:
using a lambda
if(std::any_of(l.begin(), l.end(),
[](int i){ return i == 2; })) { ... }
using std::bind
using std::placeholders::_1;
if(std::any_of(l.begin(), l.end(),
std::bind(std::equal_to<>(), 2, _1)) { ... }
Live demo
Note that std::equal_to<>() is a C++14-only option. For a C++11 compiler, use std::equal_to<int>().
Indeed the STL does not have a simple std::contains() function. Recently, there was a discussion on reddit about this topic.
Unfortunately, what came out of this is that it is considered harmful to have std::contains(), since it encourages people to write slow algorithms. Think for instance of
if (!std::contains(my_set.begin(), my_set.end(), entry)) {
my_set.insert(entry);
}
This code example essentially searches for the correct position twice: Once in contains, and once to find the insert location.
In my opinion, it would still be very helpful to have std::contains(), but so far no one was convinced yet to write a proposal.
So either use boost (as suggested by other in this thread), or write your own function which you essentially already did :-)