Re: Why doesn't <algorithm> support a range-for like syntax?
On Mar 26, 8:41 pm, Seungbeom Kim <musip...@bawi.org> wrote:
On 2012-03-26 10:20, Martin B. wrote:
I have asked a similar question a while back:
"Should (and can) the <algorithm> functions be extended by convenience
helpers that take generic containers as parameters?"
->
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/...
Personally, it hasn't been answered to my satisfaction yet.
This issue was raised back then:
template <class RandomAccessContainer, class Compare>
void sort ( RandomAccessContainer cont, Compare comp );
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last);
How do we know what is an iterator, a container, or a comparer?
and I believe it hasn't been solved yet.
(The function body containing invalid expressions such as first.end() or
*cont is not a substitution failure, so it doesn't fall under SFINAE.)
I don't understand what is the problem you are referring to. SFINAE
works fine here and allows you to disambiguate the function calls.
This, for example, works as expected:
#include <type_traits>
#include <algorithm>
#include <utility>
#include <vector>
#include <iostream>
template <class Container>
struct is_container {
template<class T>
static char foo(T* c, decltype(c->begin())* = 0, decltype(c-
end())* = 0);
static int foo(...);
static const bool value = sizeof(foo((Container*)0)) ==
sizeof(char);
};
template <class Container, class Compare>
auto sort ( Container& cont, Compare comp )
-> typename std::enable_if<is_container<Container>::value, void>::type
{
std::sort(cont.begin(), cont.end(), comp);
}
template <class Container, class F>
auto for_each( Container&& cont, F f) ->
typename std::enable_if<
is_container<
typename std::remove_reference<Container>::type
>::value, void>::type
{
std::for_each(std::forward<Container>(cont).begin(),
std::forward<Container>(cont).end(), f);
}
int main()
{
std::vector<int> v1 { 1, 3, 2};
sort(v1.begin(), v1.end(), std::less<int>());
for_each(v1, [](int i) { std::cout << i; }); // prints 1,2,3
std::cout << std::endl;
std::vector<int> v2 { 1, 3, 2};
sort(v2, std::less<int>());
for_each(v2, [](int i) { std::cout << i; }); // prints 1,2,3
}
In fact, I don't like the introduction of range-based for loop because
it creates dependency of language construct (keyword "for") on library
features (std::begin and std::end). That's, probably the only language
construct intermingled with the library. More importantly, there was
no need for this new type of loop, because this functionality could be
served better by container based for_each, like the one above. What
happened to the oft repeated motto that if something could be
implemented as a library facility it should be implemented as such and
not as a new language construct. Range based for-loop was unwarranted
and I'm surprised it got through standardization process without any
objections.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]