Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using std::transform to make a vector of pair

Tags:

c++

std

c++11

I would like to create a vector of pairs starting from a pair of vectors. For example, if A is std::vector A = [1 0 1] and B is std::vector B = [0 1 0], I want a structure std::vector C = [1 0, 0 1, 1 0] where C_i = std::pair(A_i,B_i).

I would avoid for loop through the two vector, so I'm looking for few lines code like std::transform().

I tried the following code:

std::vector<bool> boolPredLabel(tsLabels.size()); 
std::vector<bool> boolRealLabel(tsLabels.size());
std::vector<std::pair<bool,bool>> TrPrPair(tsLabels.size());
std::transform(boolRealLabel.begin(), boolRealLabel.end(), boolPredLabel.begin(), TrPrPair.begin(),std::make_pair());

This lead me to a compiler error:

error: no matching function for call to ‘make_pair()’
std::transform(boolRealLabel.begin(), boolRealLabel.end(), boolPredLabel.begin(), TrPrPair.begin(),std::make_pair());
...
note:   candidate expects 2 arguments, 0 provided
std::transform(boolRealLabel.begin(), boolRealLabel.end(), boolPredLabel.begin(), TrPrPair.begin(),std::make_pair());

The message is clear, but I don't know what pass to the binary operator. I have to admit that I don't have a clear understanding of std::transform() and I've just use it with functor.

like image 814
Luca Jungla Avatar asked May 03 '19 19:05

Luca Jungla


People also ask

Can we make pair of pair in C++?

Sets of pairs in C++ Set in C++ is an associative container and contains unique elements. All the elements once added to a specific cannot be modified. One can only remove and add elements in order to change them. Pair is defined under <utility> header and is used to couple together two pair values.

What does std :: transform do?

std::transform. std::transform applies the given function to a range and stores the result in another range, keeping the original elements order and beginning at d_first . 1) The unary operation unary_op is applied to the range defined by [first1, last1) .

Can a pair contain a vector?

A pair is a container which stores two values mapped to each other, and a vector containing multiple number of such pairs is called a vector of pairs.


1 Answers

The binary operation you pass in doesn't make any sense. std::make_pair is a function template taking two arguments, so neither can you invoke it without these two arguments, nor can it be instantiated like a function object to be passed to std::transform.

Instead, you can explicitly instantiate std::make_pair for the template types in question and pass this as to the algorithm (@RetiredNinja pointed that out but apparently felt too lazy to write an answer):

std::transform(boolRealLabel.cbegin(), boolRealLabel.cend(),
    boolPredLabel.cbegin(), TrPrPair.begin(), std::make_pair<bool, bool>);

Two other options commonly seen are a lambda,

std::transform(boolRealLabel.cbegin(), boolRealLabel.cend(), boolPredLabel.cbegin(),
    TrPrPair.begin(), [](bool a, bool b){ return std::make_pair(a, b); });

or a pointer to a function

std::pair<bool, bool> toPair(bool a, bool b)
{
    return std::make_pair(a, b);
}

std::transform(boolRealLabel.cbegin(), boolRealLabel.cend(),
    boolPredLabel.cbegin(), TrPrPair.begin(), toPair);

And for completeness, cppreference on std::transform and its binary operation argument (only relevant to the overload that acts on two input ranges):

binary_op - binary operation function object that will be applied.

The signature of the function should be equivalent to the following:

Ret fun(const Type1 &a, const Type2 &b); 
like image 184
lubgr Avatar answered Oct 22 '22 02:10

lubgr