{"action":"created","issue":{"url":"https://api.github.com/repos/ericniebler/range-v3/issues/231","labels_url":"https://api.github.com/repos/ericniebler/range-v3/issues/231/labels{/name}","comments_url":"https://api.github.com/repos/ericniebler/range-v3/issues/231/comments","events_url":"https://api.github.com/repos/ericniebler/range-v3/issues/231/events","html_url":"https://github.com/ericniebler/range-v3/issues/231","id":114580960,"number":231,"title":"Compilation failure because GCC _Safe_iterator meets SizedIteratorRange concept","user":{"login":"tonyelewis","id":9743330,"avatar_url":"https://avatars.githubusercontent.com/u/9743330?v=3","gravatar_id":"","url":"https://api.github.com/users/tonyelewis","html_url":"https://github.com/tonyelewis","followers_url":"https://api.github.com/users/tonyelewis/followers","following_url":"https://api.github.com/users/tonyelewis/following{/other_user}","gists_url":"https://api.github.com/users/tonyelewis/gists{/gist_id}","starred_url":"https://api.github.com/users/tonyelewis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tonyelewis/subscriptions","organizations_url":"https://api.github.com/users/tonyelewis/orgs","repos_url":"https://api.github.com/users/tonyelewis/repos","events_url":"https://api.github.com/users/tonyelewis/events{/privacy}","received_events_url":"https://api.github.com/users/tonyelewis/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-11-02T12:00:16Z","updated_at":"2015-11-02T22:35:23Z","closed_at":null,"body":"I'm getting a compilation failure that I think stems from a (GCC `_GLIBCXX_DEBUG`) bidirectional iterator meeting the `SizedIteratorRange` concept and then failing when range-v3 actually uses an expression like `itr_a - itr_b`.\r\n\r\nI'm guessing the troublesome subtlety may be: the iterator is actually a GCC `_Safe_iterator`, which *does* provide an `operator-()` but which just implements this by passing through to the wrapped `std::list` iterator that *doesn't* provide an `operator-()`. Hence I'm guessing the `concepts::same_type(s - i, i - s)` line in the `SizedIteratorRange` concept *is* checking that the iterator's `operator-()` exists and has a valid return type but *isn't* checking that a call to that expression is actually valid. Hence `SizedIteratorRange` isn't spotting that `itr_a - itr_b` isn't a valid expression and so doesn't get itself SFINAE-rejected as it should.\r\n\r\nSome illustrative code:\r\n\r\n~~~~~.cpp\r\n#define _GLIBCXX_DEBUG\r\n#define RANGES_NO_STD_FORWARD_DECLARATIONS\r\n\r\n#include <iostream>\r\n#include <list>\r\n#include <type_traits>\r\n\r\n#include <range/v3/all.hpp>\r\n\r\nint main() {\r\n\t// Background context:\r\n\t// Under _GLIBCXX_DEBUG, list returns a list iterator wrapped in a _Safe_iterator\r\n\t// whose iterator_category is bidirectional_iterator_tag\r\n\tusing my_range_type  = std::list< int >;\r\n\tusing my_iter_type   = decltype( std::begin( std::declval< my_range_type >() ) );\r\n\tstatic_assert(\r\n\t\tstd::is_same<\r\n\t\t\tstd::iterator_traits<my_iter_type>::iterator_category,\r\n\t\t\tstd::bidirectional_iterator_tag\r\n\t\t>::value,\r\n\t\t\"\"\r\n\t);\r\n\r\n\t// Background context:\r\n\t// range-v3 identifies the _Safe_iterator<...> as SizedIteratorRange\r\n\tusing rv3_iterator_t = ranges::range_iterator_t< my_range_type >;\r\n\tusing rv3_sentinel_t = ranges::range_sentinel_t< my_range_type >;\r\n\tusing rv3_sirc_t     = ranges::sized_iterator_range_concept<rv3_iterator_t,\r\n\t                                                            rv3_sentinel_t>;\r\n\tranges::concepts::SizedIteratorRange * my_ptr = rv3_sirc_t();\r\n\r\n\t//  **** PROBLEM HERE *****\r\n\t// Fails to compile the '...::take( 3 );' line.\r\n\t// I think that's because range-v3 treats _Safe_iterator<...> as a\r\n\t// SizedIteratorRange iterator but then cannot subtract one from another\r\n\t// (because that's not supported by the underlying list iterator)\r\n\tconst my_range_type my_values = { 1, 2, 3, 4 };\r\n\tconst auto my_first_values = my_values | ranges::v3::view::take( 3 );\r\n\tstd::cerr << *ranges::max_element( my_first_values ) << \"\\n\";\r\n\r\n\treturn 0;\r\n}\r\n~~~~~\r\n\r\nCompile command:\r\n\r\n    g++ -std=c++11 -isystem range-v3/include -ftemplate-backtrace-limit=0 rv3_safe_iter_prob.cpp\r\n\r\n(also works with `-std=c++14`; `-ftemplate-backtrace-limit=0` avoids clipped messages)"},"comment":{"url":"https://api.github.com/repos/ericniebler/range-v3/issues/comments/153179394","html_url":"https://github.com/ericniebler/range-v3/issues/231#issuecomment-153179394","issue_url":"https://api.github.com/repos/ericniebler/range-v3/issues/231","id":153179394,"user":{"login":"pfultz2","id":1306044,"avatar_url":"https://avatars.githubusercontent.com/u/1306044?v=3","gravatar_id":"","url":"https://api.github.com/users/pfultz2","html_url":"https://github.com/pfultz2","followers_url":"https://api.github.com/users/pfultz2/followers","following_url":"https://api.github.com/users/pfultz2/following{/other_user}","gists_url":"https://api.github.com/users/pfultz2/gists{/gist_id}","starred_url":"https://api.github.com/users/pfultz2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pfultz2/subscriptions","organizations_url":"https://api.github.com/users/pfultz2/orgs","repos_url":"https://api.github.com/users/pfultz2/repos","events_url":"https://api.github.com/users/pfultz2/events{/privacy}","received_events_url":"https://api.github.com/users/pfultz2/received_events","type":"User","site_admin":false},"created_at":"2015-11-02T22:35:23Z","updated_at":"2015-11-02T22:35:23Z","body":"Couldn't you just specialize `SizedIteratorRange`? Or will that break tag-dispatching?"}}