I have a container v of elements of type T, to which I apply std::minmax_element, like so:
auto min_max = std::minmax_element(v.begin, v.end);
auto min = min_max.first;
auto max = min_max.second;
I would like to unpack the results of std::minmax_element with std::tie, but I can't figure the type for the declaration:
*type?* first_it, last_it;
std::tie(first_it, last_it) = std::minmax_element(v.begin, v.end);
What would be the type of first_it and last_it?
auto [min, max] = std::minmax_element(v.begin, v.end);
std::minmax_element returns a pair of iterator as member type of passed a container, so for vector it is vector<T>::iterator:
std::vector<int> v{1,2,3,4,5,2,3};
decltype(v)::iterator first_it, last_it; // or vector<int>::iterator
std::tie(first_it,last_it) = std::minmax_element(v.begin(), v.end());
If you change for using cbegin/cend, you have to change iterator type to const_iterator.
Related
I don't understand the constructor statement in the following code. How can the iterator to the past-of-end element be added to the map as a key?
template<typename K, typename V>
class my_map {
std::map<K,V> m_map;
public:
my_map( V const& val) {
m_map.insert(m_map.end(),std::make_pair(std::numeric_limits<K>::lowest(),val));
}
};
How can the iterator to the past-of-end element be added to the map as a key?
It's not the key. It's the position of the insertion. By passing end you're saying append to the map.
The key that you're inserting is the first part of the pair. i.e. std::numeric_limits<K>::lowest().
The value that you're inserting is the second part of the pair. i.e. val.
The docs for std::map::insert are useful.
How can the iterator to the past-of-end element be added to the map as a key?
That's an incorrect conclusion. std::map::insert has several overloads. The one that is use in your call is:
iterator insert( iterator hint, const value_type& value ); // Overload 4
which does the following:
Inserts value in the position as close as possible, just prior, to hint.
I am trying to write a generic function that receives a DenseBase<Derived> parameter like this:
template<class Derived>
MatrixXd Math::gradient(const DenseBase<Derived> &y, const Dimension dimension)
{
...
Derived v = dimension == COLUMNS ? y.derived() : y.derived().transpose();
...
}
I'm having an error when I call the function in this manner:
const VectorXd g = Math::gradient(curve/ peak);
The curve/ peak expression returns a CwiseBinaryOp type, which becomes the Derived type of the Math::gradient templated function.
However, the y.derived().transpose() expression returns a Transpose<MatrixType> which yields a compilation error due to the different data type with respect to the CwiseBinaryOp
I know I can call the Math::gradient function previously storing the curve/ peak in a VectorXd to solve the problem, however, how can I write the function to handle this different datatypes?
Thank you very much.
I think I have found a solution to my own question (sorry for the poor explanation of the problem).
By using the eval() method of the DenseBase<Derived> variable y, Eigen resolves the "intermediate" expression types, such as the CwiseBinaryOp or the Transpose<MatrixType> in my particular case, to a PlainObject variable type.
So a possible solution could be:
template<class Derived>
MatrixXd Math::gradient(const DenseBase<Derived> &y, const Dimension dimension)
{
...
typename Derived::PlainObject v = dimension == COLUMNS ? y.derived().eval() : y.derived().transpose().eval();
...
}
Thank you very much for your attention
for example :
set<set<T>> outer_set;
set<T> insider_set1, insider_set2;
T a;
insider_set1.insert(a);
outer_set.insert(insider_set1);
outer_set.insert(insider_set2);
set<T>::iterator chosen_itr;
for(auto temp_set: outer_set){
if(temp_set.count(a)){
chosen_itr = temp_set.begin();
break;
}
}
T b = something(...);
*chosen_itr.insert(b);
will this code add b to the insider_set1 inside of outer_set or the chosen_itr belongs to a temporary set that was created at
auto temp_set
if chosen_itr is some random iterator how to get the real one??
As you point out in your question, you're keeping a pointer (iterator) into a temporary. You should use a reference instead:
for(auto& temp_set: outer_set){
Then the given code would be valid, with one more simple change:
chosen_itr->insert(b);
1. > iterator of a set inside a set is equal to the insider set.begin()?
no it insider_set1.begin() will point to the first element in the insider_set
to get an iterator (pointer) to the set it self the for(auto set1: outsider_sit) cant be used instead, which i was trying to avoid, is to use
for(auto itr = outsider_set.begin(); ire != outsider_set.end(); ++itr)
and then save the itr value at the chosen set.
2. will this work ?
no the itr iterator to a set> is an iterator to a constant, sets is immutable in c++ and the values inside a set can not be changed after being add even if those values are containers.
3. how to add b to a set inside the outsider_set ??
sense we cant change the values inside the set we have to remove the old value(insider_set) and insert a new value(insider_set) after being updated like so:
set<set<T>> outer_set;
set<T> insider_set1, insider_set2;
T a;
insider_set1.insert(a);
outer_set.insert(insider_set1);
outer_set.insert(insider_set2);
set<T> chosen_set;
set<T>::iterator chosen_itr; // not needed now
for(auto temp_set: outer_set){
if(temp_set.count(a)){
//chosen_itr = temp_set.begin(); // not working
chosen_set = temp_set;
break;
}
}
T b = something(...);
outsider_set.erase(chosen_set);
chosen_set.insert(b)
outsider_set.insert(chosen_set);
this solution may not be efficient but I think is the only way, besides using const_cast to insert, if any have better one please mention it.
I have a object of type of Map<String^, Object^>^. How do I iterate in C++/CX way? I am trying to use iterator but I am not clear about syntax. Documentation doesn't provide an example.
C++/CX collections follow the same principles as c++ collections, so they have iterators and begin, end functions.
IMap<Platform::String^, Platform::Object^>^ map = ref new Map<Platform::String^, Platform::Object^>();
map->Insert("key1", "val1");
map->Insert("key2", 2.0f);
// Exactly like you would iterate over a map, but instead of std::pair you have IKeyValuePair
std::for_each(begin(map), end(map), [](IKeyValuePair<Platform::String^, Platform::Object^>^ pair)
{
// do stuff
auto key = pair->Key;
auto value = pair->Value;
});
for( auto pair : map )
{
// do stuff
auto key = pair->Key;
auto value = pair->Value;
}
Also, don't forget to include collection.h and use namespace Platform::Collections.
There is a struct which contain intrusive_ptr field:
struct BranchFeedback : boost::counted_base {
...
boost::intrusive_ptr<BPredState> theBPState;
};
There is another varibale which is defined as
std::vector< std::vector< BPredState > > theFetchState;
Now I have instantiated an object
BranchFeedback theFeedback;
and want to assign theFetchState to that field
theFeedback.theBPState = theFetchState[anIndex][!anOne];
However compiler says some errors
error: no match for ‘operator=’ in theFeedback.theBPState = .....
How can I fix that?
you're passing in a BPredState, but intrusive_ptr only supports operator= for pointers to the contained type (or other intrusive_ptrs)
so you could write theBPState = &(theFetchState[anIndex][!anOne]); or get an pointer or iterator to the element and use that instead.