Nawaz's answer is most likely the right solution for most cases. However, if you are trying to do this for many instances of SomeContainerFromAThirdPartyLib<T> and only a few functions (or an unknown number of instances, but a fixed number of functions, which can happen if you write your own library), in a different way.
Suppose we are provided with the following (immutable) code:
namespace ThirdPartyLib { template <typename T> class SomeContainerFromAThirdPartyLib { public: typedef T ValueType; // not value_type! // no difference_type class iterator { public: typedef T ValueType; // not value_type! // no difference_type // obviously this is not how these would actually be implemented int operator != (const iterator& rhs) { return 0; } iterator& operator ++ () { return *this; } T operator * () { return T(); } }; // obviously this is not how these would actually be implemented iterator begin() { return iterator(); } iterator end() { return iterator(); } }; }
We define an adapter class template containing the necessary typedef for iterator_traits , and specialize it to avoid pointer problems:
namespace MyLib { template <typename T> class iterator_adapter : public T { public:
Then, for each function that we want to call using SomeContainerFromAThirdPartyLib::iterator , we define the overload and use SFINAE:
template <typename iter> typename MyLib::iterator_adapter<iter>::difference_type count(iter begin, iter end, const typename iter::ValueType& val) { cout << "[in adapter version of count]"; return std::count(MyLib::iterator_adapter<iter>(begin), MyLib::iterator_adapter<iter>(end), val); }
Then we can use it as follows:
int main() { char a[] = "Hello, world"; cout << "a=" << a << endl; cout << "count(a, a + sizeof(a), 'l')=" << count(a, a + sizeof(a), 'l') << endl; ThirdPartyLib::SomeContainerFromAThirdPartyLib<int> container; cout << "count(container.begin(), container.end(), 0)="; cout << count(container.begin(), container.end(), 0) << std; return 0; }
You can find an executable example with the required include and using at http://ideone.com/gJyGxU . Exit:
a = Hello, world
count (a, a + sizeof (a), 'l') = 3
count (container.begin (), container.end (), 0) = [in adapter version of count] 0
Unfortunately, there are reservations:
- As I said, for every function that you plan to support, an overload must be defined (
find , sort , etc.). This will obviously not work for functions from algorithm that are not yet defined. - If this is not optimized, there may be small penalties for performance at runtime.
- There are potential problems with defining the scope.
As for the latter, the question is in what namespace the overload is placed (and how to call the std version). Ideally, this would be in ThirdPartyLib so that it can be found using an argument-dependent search, but I suggested that we cannot change it. The next best option is in MyLib , but then the call should be qualified or should be preceded by using . In either case, the end user must either use using std::count; , or be careful about which calls qualify with std:: , because if std::count mistakenly used with SomeContainerFromAThirdPartyLib::iterator , this obviously will fail (the whole reason for this exercise).
An alternative, not to suggest , but to be here for completeness, would be right in the std . This will lead to undefined behavior; while this may work for you, in the standard it does not guarantee anything. If we specialized in count instead of overloading, that would be legal.