Disallow templates that are explicitly specified - c++

I want to have a wide template that 'does whatever it needs to' except for when I have explicitly specified the case.
Specifically, I am overloading operator() to use it for a matrix index of a multidimensional matrix. I also want to allow specifying an arbitrary number of indices using an iterator. Ideally I'd have the following signatures:
operator()(size_t);
operator()(size_t,size_t);
operator()(size_t,size_t,size_t);
...
template<class Iterator> operator()(Iterator,Iterator);
The problem is that operator()(size_t,size_t) is never reached, because the compiler is also able to template template<class Iterator> operator()(Iterator,Iterator). How can I avoid this?
An obvious solution is to use std::vector<size_t>::iterator instead of Iterator. I've tried this, but this narrows the usage elsewhere.
A minimal example:
#include <iostream>
class Foo
{
private:
double data[9];
public:
Foo(){};
double& operator()(size_t i, size_t j)
{
std::cout << "operator()(size_t i, size_t j)" << std::endl;
return data[0];
}
template<class Iterator>
double& operator()(Iterator first, Iterator last)
{
std::cout << "operator()(Iterator first, Iterator last)" << std::endl;
return data[0];
}
};
int main()
{
Foo bar;
bar(0,1);
}
Outputs:
operator()(Iterator first, Iterator last)
whereas I want this case to output
operator()(size_t i, size_t j)

It's almost a certainty that the reason your template gets selected by overload resolution is because the two parameters you're passing in are not really size_t. They're probably ints, or something else. If they were truly size_ts, then I would expect your non-template overload to be picked. Cleaning that up should make things work, as is, but it's simple enough to make this work in any case.
The usual approach in this kind of a situation is to use SFINAE to exclude the template from participating in overload resolution when the passed-in parameter is size_t. Something along the lines of (using C++17):
template<class Iterator,
typename=std::enable_if_t<
std::negation_v<std::is_integral_v<Iterator>>>> operator()(Iterator,Iterator)
{
// ...
}
This is your starting point. It's tempting to use std::is_same_v<Iterator,size_t>, but you'll quickly discover that this only works if you're passing in exactly a size_t. It's very easy for an int to slip in there, if you're not careful, and this is going to fall apart in this case. So you'll probably need to use std::is_integral_v. Hopefully you're not passing in floating point values anywhere, and rely on them being truncated to the next nearest integer value. If you do, you'll have to tweak this further.
The std::is_integral_v and std::enable_if_t shortcuts are available only in C++17 (as well as std::void_t), but it's simple enough to reinvent that wheel in earlier standards, if necessary.
You can also try using SFINAE in the opposite direction: have this template participate in overload resolution only if Iterator resolved to something that std::iterator_traits recognizes. The best approach depends on your specific class's requirements.

Related

Tuple wrapper that works with get, tie, and other tuple operations

I have written a fancy "zip iterator" that already fulfils many roles (can be used in for_each, copy loops, container iterator range constructors etc...).
Under all the template code to work around the pairs/tuples involved, it comes down to the dereference operator of the iterator returning a tuple/pair of references and not a reference to a tuple/pair.
I want my iterator to work with std::sort, so I need to be able to do swap(*iter1, *iter2) and have the underlying values switched in the original containers being iterated over.
The code and a small demo can be viewed here (it's quite a bit to get through): http://coliru.stacked-crooked.com/a/4fe23b4458d2e692
Although libstdc++'s sort uses std::iter_swap which calls swap, e.g. libc++'s does not, and it just calls swap directly, so I would like a solution involving swap as the customization point.
What I have tried (and gotten oooooh so close to working) is instead of returning std::pair/std::tuple from the operator* as I am doing now, is returning a simple wrapper type instead. The intent is to have the wrapper behave as if it were a std::pair/std::tuple, and allow me to write a swap function for it.
It looked like this:
template<typename... ValueTypes>
struct TupleWrapper : public PairOrTuple_t<ValueTypes...>
{
using PairOrTuple_t<ValueTypes...>::operator=;
template<typename... TupleValueTypes>
operator PairOrTuple_t<TupleValueTypes...>() const
{
return static_cast<PairOrTuple_t<ValueTypes...>>(*this);
}
};
template<std::size_t Index, typename... ValueTypes>
decltype(auto) get(TupleWrapper<ValueTypes...>& tupleWrapper)
{
return std::get<Index>(tupleWrapper);
}
template<std::size_t Index, typename... ValueTypes>
decltype(auto) get(TupleWrapper<ValueTypes...>&& tupleWrapper)
{
return std::get<Index>(std::forward<TupleWrapper<ValueTypes...>>(tupleWrapper));
}
template<typename... ValueTypes,
std::size_t... Indices>
void swap(TupleWrapper<ValueTypes...> left,
TupleWrapper<ValueTypes...> right,
const std::index_sequence<Indices...>&)
{
(std::swap(std::get<Indices>(left), std::get<Indices>(right)), ...);
}
template<typename... ValueTypes>
void swap(TupleWrapper<ValueTypes...> left,
TupleWrapper<ValueTypes...> right)
{
swap(left, right, std::make_index_sequence<sizeof...(ValueTypes)>());
}
namespace std
{
template<typename... ValueTypes>
class tuple_size<utility::implementation::TupleWrapper<ValueTypes...>> : public tuple_size<utility::implementation::PairOrTuple_t<ValueTypes...>> {};
template<std::size_t Index, typename... ValueTypes>
class tuple_element<Index, utility::implementation::TupleWrapper<ValueTypes...>> : public tuple_element<Index, utility::implementation::PairOrTuple_t<ValueTypes...>> {};
}
Full code here: http://coliru.stacked-crooked.com/a/951cd639d95af130.
Returning this wrapper in operator* seems to compile (at least on GCC) but produces garbage.
On Clang's libc++, the std::tie fails to compile.
Two questions:
How can I get this to compile with libc++ (the magic seems to lie in the conversion operator of TupleWrapper?)
Why is the result wrong and what did I do wrong?
I know it's a lot of code, but well, I can't get it any shorter as all the tiny examples of swapping tuple wrappers worked fine for me.
1st problem
One of the issues is that the ZipIterator class does not satisfy the requirements of RandomAccessIterator.
std::sort requires RandomAccessIterators as its parameters
RandomAccessIterators must be BidirectionalIterators
BidirectionalIterators must be ForwardIterators
ForwardIterators have the condition that ::reference must be value_type& / const value_type&:
The type std::iterator_traits<It>::reference must be exactly
T& if It satisfies OutputIterator (It is mutable)
const T& otherwise (It is constant)
(where T is the type denoted by std::iterator_traits<It>::value_type)
which ZipIterator currently doesn't implement.
It works fine with std::for_each and similar functions that only require the iterator to satisfy the requirements of InputIterator / OutputIterator.
The reference type for an input iterator that is not also a LegacyForwardIterator does not have to be a reference type: dereferencing an input iterator may return a proxy object or value_type itself by value (as in the case of std::istreambuf_iterator).
tl;dr: ZipIterator can be used as an InputIterator / OutputIterator, but not as a ForwardIterator, which std::sort requires.
2nd problem
As #T.C. pointed out in their comment std::sort is allowed to move values out of the container and then later move them back in.
The type of dereferenced RandomIt must meet the requirements of MoveAssignable and MoveConstructible.
which ZipIterator currently can't handle (it never copies / moves the referenced objects), so something like this doesn't work as expected:
std::vector<std::string> vector_of_strings{"one", "two", "three", "four"};
std::vector<int> vector_of_ints{1, 2, 3, 4};
auto first = zipBegin(vector_of_strings, vector_of_ints);
auto second = first + 1;
// swap two values via a temporary
auto temp = std::move(*first);
*first = std::move(*second);
*second = std::move(temp);
// Result:
/*
two, 2
two, 2
three, 3
four, 4
*/
(test on Godbolt)
Result
Unfortunately it is not possible to create an iterator that produces elements on the fly and can by used as a ForwardIterator with the current standard (for example this question)
You could of course write your own algorithms that only require InputIterators / OutputIterators (or handle your ZipIterator differently)
For example a simple bubble sort: (Godbolt)
template<class It>
void bubble_sort(It begin, It end) {
using std::swap;
int n = std::distance(begin, end);
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (*(begin+j) > *(begin+j+1))
swap(*(begin+j), *(begin+j+1));
}
}
}
Or change the ZipIterator class to satisfy RandomAccessIterator.
I unfortunately can't think of a way that would be possible without putting the tuples into a dynamically allocated structure like an array (which you're probably trying to avoid)

Nice syntax to get sized reference to vector's/array's data?

I'm wondering if there's any std:: function to get a sized pointer/reference to a vector/array's underlying data? Something better than:
const size_t(&asArray1)[N] = *(size_t(*)[N]) vec.data();
const size_t(&asArray2)[arr.size()] = *(size_t(*)[arr.size()]) arr.data();
Clarification - something I could pass to the below:
template<size_t N>
void foo(size_t(&sizedArray)[N]) {}
Update -- SOLUTION:
Use helper functions defined once, that do the appropriate casting and leave the call-site cleaner... See my answer below for helper code.
Live demo: https://onlinegdb.com/S167RI20U
What you're asking for is to decide a type (which must be done at compile time) with information only available at runtime. It is impossible.
C++20 std::span encapsulates ugly syntax in its own non-explicit constructor, so just pass it.
Before C++20, there's std::begin , std::end, std::size, which are not exactly what you need, but may help.
All this is implementable in old compiler, it does not require any special compiler support.
SOLUTION: Use helper functions defined once, that do the appropriate casting and leave the call-site cleaner... I'm surprised that helpers like these aren't available at least for std::array...
For vectors, I will admit that it's a rare use case where you have a compile-time known size for the vector. but I do have a use case where I know my vector contains at least as many elements as an array, and I want the first N of them to be processed through some algorithm. I can guarantee that that many elements are available, and include asserts to boot, etc...
Live demo: https://onlinegdb.com/S167RI20U
template<size_t N, typename T>
using CArrayPtr = T(*)[N];
template<size_t N, typename T>
auto& cArray(array<T, N>& arr) {
return *(CArrayPtr<N, T>)arr.data();
}
template<size_t N, typename T>
auto& cArray(vector<T>& vec) {
return *(CArrayPtr<N, T>)vec.data();
}

Is it possible to test whether two iterators point to the same object?

Say I'm making a function to copy a value:
template<class ItInput, class ItOutput>
void copy(ItInput i, ItOutput o) { *o = *i; }
and I would like to avoid the assignment if i and o point to the same object, since then the assignment is pointless.
Obviously, I can't say if (i != o) { ... }, both because i and o might be of different types and because they might point into different containers (and would thus be incomparable). Less obviously, I can't use overloaded function templates either, because the iterators might belong to different containers even though they have the same type.
My initial solution to this was:
template<class ItInput, class ItOutput>
void copy(ItInput i, ItOutput o)
{
if (&*o != static_cast<void const *>(&*i))
*o = *i;
}
but I'm not sure if this works. What if *o or *i actually returns an object instead of a reference?
Is there a way to do this generally?
I don't think that this is really necessary: if assignment is expensive, the type should define an assignment operator that performs the (relatively cheap) self assignment check to prevent doing unnecessary work. But, it's an interesting question, with many pitfalls, so I'll take a stab at answering it.
If we are to assemble a general solution that works for input and output iterators, there are several pitfalls that we must watch out for:
An input iterator is a single-pass iterator: you can only perform indirection via the iterator once per element, so, we can't perform indirection via the iterator once to get the address of the pointed-to value and a second time to perform the copy.
An input iterator may be a proxy iterator. A proxy iterator is an iterator whose operator* returns an object, not a reference. With a proxy iterator, the expression &*it is ill-formed, because *it is an rvalue (it's possible to overload the unary-&, but doing so is usually considered evil and horrible, and most types do not do this).
An output iterator can only be used for output; you cannot perform indirection via it and use the result as an rvalue. You can write to the "pointed to element" but you can't read from it.
So, if we're going to make your "optimization," we'll need to make it only for the case where both iterators are forward iterators (this includes bidirectional iterators and random access iterators: they're forward iterators too).
Because we're nice, we also need to be mindful of the fact that, despite the fact that it violates the concept requirements, many proxy iterators misrepresent their category because it is very useful to have a proxy iterator that supports random access over a sequence of proxied objects. (I'm not even sure how one could implement an efficient iterator for std::vector<bool> without doing this.)
We'll use the following Standard Library headers:
#include <iterator>
#include <type_traits>
#include <utility>
We define a metafunction, is_forward_iterator, that tests whether a type is a "real" forward iterator (i.e., is not a proxy iterator):
template <typename T>
struct is_forward_iterator :
std::integral_constant<
bool,
std::is_base_of<
std::forward_iterator_tag,
typename std::iterator_traits<T>::iterator_category
>::value &&
std::is_lvalue_reference<
decltype(*std::declval<T>())
>::value>
{ };
For brevity, we also define a metafunction, can_compare, that tests whether two types are both forward iterators:
template <typename T, typename U>
struct can_compare :
std::integral_constant<
bool,
is_forward_iterator<T>::value &&
is_forward_iterator<U>::value
>
{ };
Then, we'll write two overloads of the copy function and use SFINAE to select the right overload based on the iterator types: if both iterators are forward iterators, we'll include the check, otherwise we'll exclude the check and always perform the assignment:
template <typename InputIt, typename OutputIt>
auto copy(InputIt const in, OutputIt const out)
-> typename std::enable_if<can_compare<InputIt, OutputIt>::value>::type
{
if (static_cast<void const volatile*>(std::addressof(*in)) !=
static_cast<void const volatile*>(std::addressof(*out)))
*out = *in;
}
template <typename InputIt, typename OutputIt>
auto copy(InputIt const in, OutputIt const out)
-> typename std::enable_if<!can_compare<InputIt, OutputIt>::value>::type
{
*out = *in;
}
As easy as pie!
I think this may be a case where you may have to document some assumptions about the types you expect in the function and be content with not being completely generic.
Like operator*, operator& could be overloaded to do all sorts of things. If you're guarding against operator*, then you should consider operator& and operator!=, etc.
I would say that a good prerequisite to enforce (either through comments in the code or a concept/static_assert) is that operator* returns a reference to the object pointed to by the iterator and that it doesn't (or shouldn't) perform a copy. In that case, your code as it stands seems fine.
Your code, as is, is definitly not okay, or atleast not okay for all iterator categories.
Input iterators and output iterators are not required to be dereferenceable after the first time (they're expected to be single-pass) and input iterators are allowed to dereference to anything "convertible to T" (§24.2.3/2).
So, if you want to handle all kinds of iterators, I don't think you can enforce this "optimization", i.e. you can't generically check if two iterators point to the same object. If you're willing to forego input and output iterators, what you have should be fine. Otherwise, I'd stick with doing the copy in any case (I really don't think you have another option on this).
Write a helper template function equals that automatically returns false if the iterators are different types. Either that or do a specialization or overload of your copy function itself.
If they're the same type then you can use your trick of comparing the pointers of the objects they resolve to, no casting required:
if (&*i != &*o)
*o = *i;
If *i or *o doesn't return a reference, no problem - the copy will occur even if it didn't have to, but no harm will be done.

How to implement own function to std::vector?

I would like to add a function that returns the .size() value as an integer, instead of unsigned integer.
Edit: Due to comments, i explain more detailed:
I have code:
int something = 3;
if(arr.size() > something)
Which will produce compiler warning, and i dislike adding (int) to every place where i have this.
So, a solution i thought it would be nice to have sizei() function:
int something = 3;
if(arr.sizei() > something)
Which wouldnt produce a warning.
So, im not wanting to create a separate function, but a function in the std::vector itself.
Edit: Seems like the only way to do this is to create another function, such as:
template <typename T>
inline int sizei(const T &arr){
return (int)arr.size();
}
On the positive side: this doesnt seem to increase my executable size at all.
First of all, why would you want that? I don't see any reason, or advantage:
Anyway, you can do this:
template<typename T>
int size(const std::vector<T> &v) { return (int) v.size(); }
//use
std::vector<int> ints;
//...
int count = size(ints);
Still I don't see any point in doing that. You can simply write:
int count = (int) ints.size();
But I would still say its not better than the following :
size_t count = ints.size(); //don't prefer anything over this. Always use size_t
Advice: avoid using int for size. Prefer size_t.
As for the edit in your question. Why don't you use size_t as:
size_t something = 3;
if(arr.size() > something)
No warning. In my opinion, if you choose the data type consistently throughout your program, you wouldn't come across a situation when you've to compare int with size_t which is defined as unsigned integral type.
Or if there is some legacy code which you've to work with, and which use int for size, then I think its better to use explicit cast when you need it, instead of adding a function in the framework itself, which hides the potential problem:
int something = /*some legacy code API call or something */;
if(arr.size() > (size_t) something)
//or even better;
size_t something = (size_t) /*some legacy code API call or something */;
if(arr.size() > something)
As a rule, in C and C++ you should never use an unsigned type such as size_t to restrict the domain. That's because (1) these languages provide no range checking, and (2) they do provide unreasonable implicit promotions. No range checking means (1) no advantage, and unreasonable implicit promotions means (2) very undesirable disadvantages, so it's plain stupid thing to do: no advantage, very undesirable disadvantages.
However, the standard libraries for these languages do that. They do it for historical reasons only, caught irreversibly in early decisions which at one time made sense. This has both extremely silly consequences such as C99 requiring 17 (!) bits for ptrdiff_t, and it has the aforementioned extremely undesirable consequences such as using inordinately much time on hunting down bugs resulting from implicit promotions (etc.). For example, in C++ you are practically guaranteed that std::string( "bah!" ).length() < -5 – which can easily trip you up and anyway is as silly as it is possible to design.
Now, you can't infuse new member functions in std::vector, but you can add a freestanding function. A good name is countOf. Template it so that it can be applied to just about anything (raw arrays, vectors, etc.).
The triad of functions startOf, endOf and countOf were, as far as I know, first identified by Dietmar Kuehl. C++0x will have std::begin and std::end, but AFAIK no corresponding std::size. In the meantime you can just define this support, which allows you to treat any kinds of container plus raw arrays the same.
An example implementation & further discussion is provided at my blog.
EDIT Adding some code, because it's requested in the comments.
Detection of suitable iterator type:
template< typename Type >
struct It
{
typedef typename Type::iterator T;
};
template< typename Type >
struct It< Type const >
{
typedef typename Type::const_iterator T;
};
template< typename ElemType, Size N >
struct It< ElemType[N] >
{
typedef ElemType* T;
};
And the countOf, startOf and endOf functions, using that deduced iterator type:
template< typename T >
inline Size countOf( T const& c ) { return static_cast<Size>( c.size() ); }
template< typename T, Size N >
inline Size countOf( T (&)[N] ) { return N; }
template< typename T >
inline typename It<T>::T startOf( T& c ) { return c.begin(); }
template< typename T, Size N >
inline T* startOf( T (&a)[N] ) { return a; }
template< typename T >
inline typename It<T>::T endOf( T& c ) { return c.end(); }
template< typename T, Size N >
inline T* endOf( T (&a)[N] ) { return a + N; }
where Size is a typedef for ptrdiff_t.
Note: in 64-bit Windows int (and even long) is 32-bit. Hence, int is in general not sufficient for a really large array. ptrdiff_t is guaranteed to be able to represent the difference between any two pointers, when that difference is well-defined.
Cheers & hth.
You can derive from vector as follows:
template<typename T>
class my_vector : public vector<T>
{
// missing constructors!
int size() const
{
if (vector<T>::size() > INT_MAX)
throw std::range_error("too many elements in vector");
return (int) vector<T>::size();
}
};
The down-side is that you'll have to define and forward constructors yourself.
I would favor using an explicit cast to int instead of a function: static_cast<int> (v.size()). Even better would be to always use size_t when dealing with memory sizes. For example, favor for (size_t i=0; i < v.size(); ++i) over for (int i=0; i < (int) v.size(); ++i). Use the right type for the job. You should not be comparing std::vector sizes with a signed type.
See the following references for why you should prefer size_t to int:
Using size_t appropriately can improve the portability, efficiency, or readability of your code. Maybe even all three.
unsigned int vs. size_t
Is it good practice to use size_t in C++?
When should I use std::size_t?
Quick answer for .size() is: no. For vectors, the possibilities are its storage value and the alloc method (default new/delete, not normally overridden) along with methods that utilize InputIterator.
Most are going to ask why would you want a different size_t. If it's just the annoy warnings, you can cast or use unsigned integers to iterate/check against size(). (If it's a lot of code, you going to have to find/replace)... If it is handling empty conditions, you could wrap the vector in a class with some smarts. As an aside, since I don't know your problem at hand, a good place to look for ideas and already implemented features is std library's algorithms such as sort, for_each, find, and lots more.
For std algorithms, see: http://www.sgi.com/tech/stl/table_of_contents.html
While #Nawaz, in my opinion, provided the most appropriate answer, if you really want to add an additional member to std::vector<> it isn't really possible. #zvrba provided the only way that could be accomplished, but as stated in the comments there the std container types do not have virtual destructors and therefore are not meant to be subclassed from.
However, you could implement a new type of vector using a container adaptor, like this:
template <class T>
class my_vector
{
public:
int size_i() const
{
return static_cast<int>(container_.size());
}
private:
std::vector<T> container_;
};
The drawback here is that you have to explicitly expose the functions of the container that you actually need to support. If you are using 'std::vector' normally throughout your code, this would likely be a significant change. See 'std::queue' for an implementation example of a container adaptor.

C++: overloading list.end() and list.begin() methods for constant iterators

I'm still trying to implement my own version of LinkedList class and now I have problems with overloading methods for constant iterators. For example, when I try to print out list using this code:
cout << "citer:" << endl;
for (UberList<int>::CIter it = ulist.begin(); it != ulist.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
I have these errors:
Error E2034 UberList2.cpp 532: Cannot convert 'UberList<int>::Iter' to 'UberList<int>::CIter' in function main()
Error E2094 UberList2.cpp 532: 'operator!=' not implemented in type 'UberList<int>::CIter' for arguments of type 'UberList<int>::Iter' in function main()
so as far as I understood, it means that those usual end and begin iterator methods are used. Here's how these methods are declared in my class:
Iter begin();
Iter end();
CIter begin() const;
CIter end() const;
and
template<class T>
typename UberList<T>::Iter UberList<T>::begin()
{
Iter it;
it.curr = head;
return it;
}
template<class T>
typename UberList<T>::Iter UberList<T>::end()
{
Iter it;
it.curr = tail->next;
return it;
}
template<class T>
typename UberList<T>::CIter UberList<T>::begin() const
{
CIter it;
it.ccurr = head;
return it;
}
template<class T>
typename UberList<T>::CIter UberList<T>::end() const
{
CIter it;
it.ccurr = tail->next;
return it;
}
Is there any way I can force my program to use these const methods for constant iterators instead of usual ones? I'd be glad to hear any advice.
Oh and here's the code of my class in one file just in case: http://pastebin.com/Jbvv5Hht
You should provide a conversion from Iter to CIter. Standard containers do (Table 65, in 23.1 "Container requirements", says that X::iterator is convertible to X::const_iterator)
The caller can ensure that the const overload is called by using a const reference, but you shouldn't force them to do that, because they will have to write something like:
UberList<int>::CIter it = static_cast<const UberList<int> &>(ulist).begin()
If you provide the "required" conversion then there's no need for your caller to do anything special: your original code will work, just as it does for standard containers.
Some more comments to the OP's code. Consider separating that gigantic uberl33tlist class and break it up into smaller files. Seeing all those friends class declaration is making me rather uncomfortable. There are also some tricky semantics When you're using stuff like
friend class UberList;
friend class CIter;
In some cases those statements also end up forward declaring those classes if they don't exist yet. There's also something not quite right looking about your assignment operator here:
UberList<T> operator = (const UberList<T>& OL)
{
UberList<T> NL = new (OL);
return NL;
}
Also in your main you have
it2++;
ulist.insertAfter(b, it2);
//...
You're using postfix operator ++ for it2 but didn't implement that your iterator class. Borland accepts it by using the prefix instead but gives a warning. Gcc actually flags that as an error and rejects the code. Might want to look into that
Sigh: there's a level of hackery here designed to hide the fact that conceptually what you want to do cannot be done automatically in C++ because it doesn't understand variance. Some other languages (including Ocaml) do.
If you have a functor (that's a template class to C++ programmers), the question is how it and various functions behave with a variance of the parameter, such as a conversion from T to T const. What you really want is this:
List<T> --> List<T const>
in other words you want the List functor to be covariant. But no, it isn't .. so actually the List template isn't a functor at all, because functors must be structure preserving and the conversion isn't reflected as required. In turn this means either C++ templates are broken OR the concept of const is broken, because a type system that doesn't support parametric polymorhism is broken by specification :)
Providing "const_iterator" does not solve this problem, it simply patches up the break. Where is the volatile and const_volatile version? How about double indirections?
If you don't understand double indirections: consider a tree of vectors of T, that's two templates:
Tree<Vector<T>>
The best solution here is to give up supporting const_iterator. Just don't bother. It's confused anyhow: how about "const vector"? What's that? A vector you can't make longer but it still allows you to write the elements?
The actual requirement is that transforms commute, for example:
vector<T> const == vector<T const>
[or they anti-commute if the transform is contra-variant]
The fact this doesn't happen shows that vector isn't functorial, in other words, templates can't be used effectively for parametric polymorphism. If you want to really get your knickers tied in a knot consider templates with function arguments and ask about the variance of the function's return type and parameters, and how this might impact the container. A good example is how to compose a two functions so they work on a pair. What if they're mutators, how does "const" work then?
You need
teamplate<class T> bool operator!=(UberList<T>::CIter,UberList<T>::CIter);
It's using the regular begin method because the variable is not const. So one way of fixing it is to make another (reference) variable that is const:
UberList<int> const & culist = ulist;
for (UberList<int>::Citer it = culist.begin(); ...)
Alternatively, use a const_cast.