I'm trying to create a function that works with both pointers and iterators (I want the testing process to iterate over collections, as well as the flexibility of using arrays to expose the C library without packaging). I want to do this using as little boiler plate code as possible and not relying on the Boost or C ++ 11 functions. Ok, I do not do this, my specification is requirements.
So far, the solution is quite simple: a function template parameterizing on an iterator. The problem is that I want the iterator to refer to const values; partially to avoid stupid errors (changing something of a strictly entered value) and partially to allow the compiler to use a constant for optimization (values are used in narrow loops where every optimization is welcome.
Consider the following example:
void foo(vector<int>::const_iterator it)
{
int tmp = it[5];
}
void bar(const int *it)
{
int tmp = it[5];
}
template<class T>
void baz(T it)
{
it[5] = 7;
int tmp = it[5];
}
template<class T>
void qux(T it)
{
int tmp = it[5];
}
template<class T>
void quux(const T it)
{
it[5] = 7;
int tmp = it[5];
}
vector<int> a(10);
const vector<int> b(10);
int c[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const int d[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foo(a.begin());
foo(b.begin());
bar(c);
bar(d);
baz(a.begin());
baz(c);
qux(a.begin());
qux(b.begin());
qux(c);
qux(d);
quux(a.begin());
quux(c);
Foo and bar are working as intended; I can read the values, and if I try to comment out lines 1 or 2, I get a compilation error. In addition, I can call functions with both constant and non-constant values. However, this requires code duplication.
Baz , . . , const ( 5 6 ), , (l. 3 ). (qux, l. 4) const non-cost. ( ), , const . , constost ( , constness "" ).
- quux, , , . - , foo bar, . , / , / (const ), const . 5 ( 8 9), . , , 7-9, 5 .
, , / (. ), ( , baz, ). , .., . .
template<class T>
void quux_(T it)
{
it[5] = 7;
int tmp = it[5];
}
void quux(const int* it) { quux_<const int*>(it); }
void quux(std::vector<int>::const_iterator it) { quux_<std::vector<int>::const_iterator>(it); }
, const ( const_iterator, , , , ++ - , , ). , ( 4 ). , - foo bar.
template<> struct constify<typename std::vector<int>::iterator> { typedef typename std::vector<int>::const_iterator type; };
template<> struct constify<std::vector<int>::const_iterator> { typedef std::vector<int>::const_iterator type; };
template<class U> struct constify<U*> { typedef const U* type; };
template<class U> struct constify<const U*> { typedef const U* type; };
template<class T>
void quux(T p_it)
{
typename constify<T>::type it = p_it;
int tmp = it[5];
}
- ? , constify - , , .