|
Boost : |
Subject: Re: [boost] [range] [general] making member functions SFINAE-friendly
From: Pyry Jahkola (pyry.jahkola_at_[hidden])
Date: 2013-02-19 13:18:08
On 2013-02-19 17:01:14 +0000, Jonathan Wakely said:
> On 19 February 2013 17:00, Thorsten Ottosen wrote:
>>
>> Would using enable_if on size() not solve the problem?
>
> It's not a template function, so you can't.
I'm not suggesting to actually use the following hack in
boost::iterator_range, but since you claimed the opposite, this trick
has the wished SFINAE behavior in C++11.
/Pyry.
* * *
#include <list>
#include <vector>
struct zero {
template <typename T>
T && operator+(T && x) const { return std::forward<T>(x); }
};
template <typename T> struct always_zero { using type = zero; };
template <typename I> struct iterator_range {
I b, e;
iterator_range(I b, I e) : b(b), e(e) {}
// SFINAE trick:
template <typename Ignore=void>
auto size(typename always_zero<Ignore>::type z={}) -> decltype(z + e - b) {
return e - b;
}
};
using std::begin;
using std::end;
template <typename R>
auto make_iterator_range(R const & r) -> iterator_range<decltype(begin(r))> {
return iterator_range<decltype(begin(r))>(begin(r), end(r));
}
int main() {
std::list<int> list;
std::vector<int> vector;
auto r1 = make_iterator_range(list); // no error
auto r2 = make_iterator_range(vector);
// r1.size(); // compiler error
r2.size();
}
* * *
-- Pyry Jahkola pyry.jahkola_at_[hidden] https://twitter.com/pyrtsa
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk