Re: want to pass vector<foo*> to fn expecting vector<const foo*>
On 20.04.2013 23:49, Jonathan Thornburg wrote:
Martin Ba <0xcdcdcdcd@gmx.at> wrote:
Maybe boost::ptr_vector or Boost Range can help?
Yes, boost::ptr_vector is a useful abstraction here. ...
... Or at least these would be possiblities if the real code the
pointers were *owning* pointers. But in my real code they're not --
they're "weak pointers" to objects which are NOT owned by the
std::vector... so it seems to me that raw C++ pointers are
appropriate.
Finally, note that the same problem I've described can apply to any
container, not just std::vector. In fact, in June 2011 we had a
discussion in this newsgroup about (what I would say is essentially)
this same issue applied to std::pair<int,int> vs std::pair<const
int,int>: ... ...
The consensus of replies to that posting was that no, the use of
reinterpret_cast<...> is NOT portable, and that at present there is
no good solution to this problem. :(
I had a try with Boost.Range and it would appear that it is able to
solve the problem via an `any_range`. Given that your original
example:
+ + + +
void print_vector_of_intervals(const std::vector</* const */ interval*>&
vci)
{
for (int i = 0 ; i < static_cast<int>(vci.size()) ; ++i)
{
const interval* pI = vci.at(i);
assert(pI != NULL);
const interval& I = *pI;
cout << "interval " << i << " = "
<< "[" << I.min() << ", " << I.max() << "]" << "\n";
}
}
+ + + +
didn't really care what kind of sequence it got passed, I suggest the
following: (tested with VS2012 Express + boost 1.53):
+ + + +
#include <vector>
#include <iostream>
#include <boost/range.hpp>
#include <boost/range/any_range.hpp>
typedef std::vector<int*> VecT;
typedef std::vector<const int*> CVecT;
typedef boost::any_range<const int*,
boost::forward_traversal_tag,
const int*,
std::ptrdiff_t> IntCPtrRange;
void fn(IntCPtrRange const& r) {
for(const int* ptr : r) {
int val = *ptr;
std::cout << "Val: " << val << "\n";
}
}
int main(int argc, char* argv[])
{
using namespace std;
VecT vec;
// Note: Toy example. Don't care 'bout leaks ...
vec.push_back(new int(42));
vec.push_back(new int(23));
CVecT cvec(begin(vec), end(vec));
// Can pass vector of non-const pointer to any_range
// that uses const-ptr:
fn(vec);
// vec<const T> works as well:
fn(cvec);
return 0;
}
+ + + +
Seems to work fine.
cheers,
Martin
--
Good C++ code is better than good C code, but
bad C++ can be much, much worse than bad C code.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]