Bug 44963 - [DR 1334] Ambiguous function overload using __gnu_cxx::crope with std::back_inserter in c++0x mode
Summary: [DR 1334] Ambiguous function overload using __gnu_cxx::crope with std::back_i...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.4.2
: P3 normal
Target Milestone: 4.5.2
Assignee: Paolo Carlini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-16 10:28 UTC by Alexander Dubov
Modified: 2010-09-02 00:13 UTC (History)
2 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build: x86_64-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-08-08 14:47:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Dubov 2010-07-16 10:28:17 UTC
The example program below will exhibit the problem when compiled with
-std=c++0x or gnu++0x flag. The problem is particularly unfortunate, as rope is designed for use with back_inserter style constructs.

Example program:
#include <iostream>
#include <ext/rope>

using namespace std;

int main(int argc, char **argv)
{
        __gnu_cxx::crope line("test");
        auto ii(back_inserter(line));

        *ii++ = 'm';
        *ii++ = 'e';

        cout << line << endl;
        return 0;
}

Compilation error message:
testrope1.cpp: In function &#8216;int main(int, char**)&#8217;:
testrope1.cpp:11: error: ambiguous overload for &#8216;operator=&#8217; in &#8216;ii.std::back_insert_iterator<_Container>::operator++ [with _Container = __gnu_cxx::rope<char, std::allocator<char> >](0).std::back_insert_iterator<_Container>::operator* [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]() = 'm'&#8217;
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include/g++-v4/bits/stl_iterator.h:415: note: candidates are: std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(typename _Container::const_reference) [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include/g++-v4/bits/stl_iterator.h:423: note:                 std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]
testrope1.cpp:12: error: ambiguous overload for &#8216;operator=&#8217; in &#8216;ii.std::back_insert_iterator<_Container>::operator++ [with _Container = __gnu_cxx::rope<char, std::allocator<char> >](0).std::back_insert_iterator<_Container>::operator* [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]() = 'e'&#8217;
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include/g++-v4/bits/stl_iterator.h:415: note: candidates are: std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(typename _Container::const_reference) [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.2/include/g++-v4/bits/stl_iterator.h:423: note:                 std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = __gnu_cxx::rope<char, std::allocator<char> >]
Comment 1 Jonathan Wakely 2010-07-16 12:00:47 UTC
confirmed, the ambiguity comes because crope::const_reference is a typedef for char, not const char&

  template <class _CharT, class _Alloc>
    class rope : public _Rope_base<_CharT, _Alloc>
    {
    public:
      typedef _CharT value_type;
      typedef ptrdiff_t difference_type;
      typedef size_t size_type;
      typedef _CharT const_reference;
Comment 2 Paolo Carlini 2010-07-16 13:12:09 UTC
Bah, I'm afraid this is going to be a wontfix. Certainly the back_insert_iterator assignment operators are fine per se in C++0x mode, and I don't think we really want to, eg, add specializations of back_insert_iterator & co for rope...
Comment 3 Paolo Carlini 2010-07-16 13:22:57 UTC
Wait a minute, however, what about vector<bool>? We can ignore the super-legacy rope, but is the vector<bool> version of the problem known to LWG?
Comment 4 Paolo Carlini 2010-07-16 13:31:34 UTC
It is, LWG 1334. I'll try to figure in Rapperswil if there is enough consensus about the resolution to warrant an early implementation even if the issue isn't really resolved.
Comment 5 Alexander Dubov 2010-07-16 19:21:58 UTC
Why is rope super-legacy? It had not enough attention to it, true, but it's a very convenient class in certain cases.

Does the bug resolution means that no more changes/updates are expected for gcc supplied rope, so external implementation should be preferred? And if such is the case, shouldn't rope class be marked as deprecated, so that similar functionality class can be proposed for addition elsewhere, in boost, for instance?
Comment 6 Jonathan Wakely 2010-07-16 20:33:59 UTC
what resolution? this bug has no resolution, it's been suspended until we know what the C++ committee decide to do about DR 1334.  The proposed resolution to DR 1334 would solve the problem with rope.
Comment 7 Paolo Carlini 2010-07-16 21:37:37 UTC
Yes, it's considered super-legacy vs hash_map, for example, which is just legacy. The criterion is very simple: we are missing active maintainers. Just for your information, I'm the one who voted for keeping it in the past, because several times other library maintainers were tempted to simply remove it completely from v3 for that reason. It will slowly rot, will not include new ideas which are being included in all the other containers, will not be tested in less common targets, the performance will deteriorate (because, for example, if nobody really knows the details of the implementation, the bits having to do will concurrency will just use slow locks even when not strictly necessary). Thus, if you, or somebody else you are in contact with, really like it, please consider investing time to study its internals and help maintaining it.

That said, this specific issue is just an example of LWG 1334, which is about proxy iterators much more generally.
Comment 8 Paolo Carlini 2010-08-08 14:47:08 UTC
Instead of waiting for the resolution of DR 1334, I'm going to resolve this by adding in C++0x mode the overload:

  operator=(const typename _Container::value_type&)

which is where 1334 is actually going.  In any case should be safe from the ODR / compatibility points of view and will allow more testing of C++0x mode.

Comment 9 paolo@gcc.gnu.org 2010-08-08 14:55:08 UTC
Subject: Bug 44963

Author: paolo
Date: Sun Aug  8 14:54:51 2010
New Revision: 163001

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163001
Log:
2010-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/44963
	* include/bits/stl_iterator.h (insert_iterator<>::
	operator=(const typename _Container::value_type&,
	back_insert_iterator<>::
	operator=(const typename _Container::value_type&),
	front_insert_iterator<>::
	operator=(const typename _Container::value_type&))): Add
	in C++0x mode.
	* testsuite/ext/rope/44963.cc: New.
	* testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust
	dg-error line number.

Added:
    trunk/libstdc++-v3/testsuite/ext/rope/44963.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/stl_iterator.h
    trunk/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc

Comment 10 paolo@gcc.gnu.org 2010-08-08 14:56:27 UTC
Subject: Bug 44963

Author: paolo
Date: Sun Aug  8 14:56:10 2010
New Revision: 163002

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163002
Log:
2010-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/44963
	* include/bits/stl_iterator.h (insert_iterator<>::
	operator=(const typename _Container::value_type&,
	back_insert_iterator<>::
	operator=(const typename _Container::value_type&),
	front_insert_iterator<>::
	operator=(const typename _Container::value_type&))): Add
	in C++0x mode.
	* testsuite/ext/rope/44963.cc: New.

Added:
    branches/gcc-4_5-branch/libstdc++-v3/testsuite/ext/rope/44963.cc
Modified:
    branches/gcc-4_5-branch/libstdc++-v3/ChangeLog
    branches/gcc-4_5-branch/libstdc++-v3/include/bits/stl_iterator.h

Comment 11 Paolo Carlini 2010-08-08 14:57:03 UTC
Fixed for 4.5.2.
Comment 12 Alexander Dubov 2010-08-09 06:02:11 UTC
(In reply to comment #11)
> Fixed for 4.5.2.
> 

Thanks.
I've been looking into rope data structure per your advice, and indeed, it needs a lot of fixes. It can probably use canned smart pointers and vstrings for added simplicity and it doesn't seem fully thread safe to me in its current form.

Hopefully, I'll have some time soon to give a try at reimplementing it.
Comment 13 Paolo Carlini 2010-08-09 07:31:01 UTC
Any help with it would be appreciated, thanks. In general, if you mean to contribute it's a good idea to sort out first the Copyright Assignment paperwork, which is actually very simple but takes time: http://gcc.gnu.org/contribute.html Thus get the forms from assignments@. Then, it would be nice if before larger rewrites we could figure out more localized improvements to rope.
Comment 14 David Fang 2010-09-01 23:52:19 UTC
I also ran into this problem with std::back_insert_iterator of vector<bool> on gcc-4.4.4's libstdc++ (in C++0x mode).  
Any chance of a 4.4.5 backport, or is the 4.5.x target final?
Comment 15 Paolo Carlini 2010-09-01 23:59:10 UTC
From now on I will not apply *any* patch not fixing extremely serious regressions to the 4.4.x branch.
Comment 16 David Fang 2010-09-02 00:08:22 UTC
(In reply to comment #15)
> From now on I will not apply *any* patch not fixing extremely serious
> regressions to the 4.4.x branch.

Is 'rejects-valid' serious enough?  
(This compiles with earlier versions.)
Comment 17 Paolo Carlini 2010-09-02 00:13:16 UTC
No.