问题
I am writing a stl-like container class which has the following functions:
Iterator begin(){
return Iterator(data_.begin(), 1);
}
ConstIterator begin() const{
return ConstIterator(data_.begin(), 1);
}
I think I could make one function to replace both:
template <typename itr0, typename itr1>
itr0 begin(){
return itr1(data_.begin(), 1);
}
and when I call the following, the code is generated in compile time:
Iterator it = foo.begin<Iterator, Iterator>();
ConstIterator it = foo.begin<ConstIterator const?, ConstIterator>();
My first question is, what typename is actually ConstIterator begin() const?
Secondly, is there a way to make it so that this metaprogramming is transparent from outside of the class? i.e. I could still use the following code to call begin() as if it was written in a standard way?
C foo;
const C foo2;
Iterator it = foo.begin();
ConstIterator it = foo2.begin();
回答1:
Unfortunately you'll need to define the two methods separately since, as you've noted, their signature differs by the const modifier. There's no template wizardry available that can overcome that (at least none that I'm aware of).
You can however use a number of different techniques to combine their implementations into a single method. Here's one such option that avoids the need for any const_cast'ing:
struct Container
{
template< typename I, typename C >
friend I begin_impl( C & c ){
return I( c.data_.begin(), 1 );
}
Iterator begin(){
return begin_impl< Iterator >( *this ); // *this is "Container"
}
ConstIterator begin() const{
return begin_impl< ConstIterator >( *this ); // *this is "Container const"
}
};
See here for more options.
来源:https://stackoverflow.com/questions/10308049/c-function-code-generalization-using-template