Re: Splitting vector<pair<int,int> > to pair<vector<int>,vector<int>
On Apr 21, 10:52 pm, Daniel Kr?gler <daniel.krueg...@googlemail.com>
wrote:
Abhishek Padmanabh schrieb:> Thanks for the explanation, Daniel and the
insight on std::set.[...]
I will be upfront with you: Several of the tested techniques
have severe problems in the code:
No worries, thank you for your valuable inputs. :)
1) You should additionally add #include <ostream> in all
examples, otherwise it's not guaranteed that the needed
operator<<(basic_ostream<char,traits>&, const char*)
is available via #include <iostream>. You also need
<stddef.h> because you use size_t in PrintVector.
About size_t -> I should have had qualified it with the std::
namespace. Otherwise, I think I need not explicitly include <cstddef>
as std::vector and std::allocator have size_type typedef-ed on it and
I would expect that size_t is available with <vector>. <vector> should
include all the dependent headers and explicitly adding its
dependencies should not be needed for people who use it. In any case,
std::vector<T>::size_type is what I should have had put it as.
About operator<< with ostream for const char* -> I guess since
<iostream> has cout etc declared it should also contain the operator<<
overloads that would be needed for it to work with atleast the
fundamental types. Any new type introduced, for example, std::string
should have the overload provided in its own respective headers that
defines it. If std::cout << int works, I would expect std::cout <<
const char* works. Is it not the case?
2) The syntax used in trial #1 to define the static member
is invalid. Most probably you want to use this one:
template<typename T>
int IsEvenIndex<T>::index = 0;
Right. Since I provided the definition just for the int
specialization, I should have had atleast put it with an empty
template tag:
template<>
int IsEvenIndex<int>::index = 0;
But what you suggest is a generic one that should take care of the
definition for all template instantiations. That's an error on my
part.
4) The insertion used in trial 2 is needlessly complicated
and could be replaced by the simple assignment
myanotherintVector.assign(itend, myintVector.end());
Yes, assign would work as well. But I don't necessarily consider
insert as complicated because it takes an extra argument. It's just
there are 2 ways and there may be more and that its just a matter of
choice.
6) Some conclusions are basically wrong, e.g. this one
from #2: "Now, how would this predicate be passed? By
reference or by value? This is unspecified by the standards."
The standard says that the predicates *are passed* by value.
I guessed, that implementations were allowed to copy them freely but
not that they could not accept the arguments by reference. If that is
not the case, please feel to correct me.
7) Further on the examples would be more readable, if you
had used a simpler initialization technique, e.g. a single
loop like this:
for (int i = 1; i <= 10; ++i) {
myintVector.push_back(10 * i);
}
The individual push_back's use a lot of space and more
severe: I had to check each single push_back to check,
whether the series of elements follow a special rule or not.
This rule is directly implied in the loop above.
Yeah, I understand. :) I replaced those.
8) The easy fix of #2 is to use an external state, that is
replacing the index int member in IsEvenIndex by int& index
and adding a second c'tor argument. Note that this externally
stored index has a similar role as the external state of the
referenced refVec.
Now, aren't you going against your own correction? Storing a reference
member with a functor?
But it can be advantagous, if a functor is both CopyConstructible
and Assignable, because both requirements are given by
normal function pointers. So, if you would like to be flexible
enough to use a functor where you would use a function
pointer, both requirements should be fulfilled.
I wonder how that can be advantageous? The problem comes when the
functor has state that has to be maintained while copy/assign -
function pointers cannot have state unless they use a global/static
variable or a reference/pointer to an external object.
I was discussing advantages in general, not for this special
example which needs state. When you need state, a functor
is often the right choice, but you could also use tr1::bind
with a function pointer (with an additional argument accepting
the state), and transferring the state via the tr1:bind argument.
Yeah, but when you used bind, it doesn't remain a function pointer
anymore. Does it?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]