diff mbox

[v3] Implement LWG 2825, LWG 2756 breaks class template argument deduction for optional.

Message ID CAFk2RUa1gqaEgxUpcByBBCorL0Y7K81M+Sbi=q_eUdf1XXu52A@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Jan. 30, 2017, 11:47 a.m. UTC
Tested on Linux-x64.

2017-01-30  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Implement LWG 2825, LWG 2756 breaks class template argument
    deduction for optional.
    * include/std/optional: Add a deduction guide.
    * testsuite/20_util/optional/cons/deduction_guide.cc: New.

Comments

Jonathan Wakely Jan. 30, 2017, 1:28 p.m. UTC | #1
On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
>Tested on Linux-x64.

OK, thanks.
Jonathan Wakely Jan. 30, 2017, 1:36 p.m. UTC | #2
On 30/01/17 13:28 +0000, Jonathan Wakely wrote:
>On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
>>Tested on Linux-x64.
>
>OK, thanks.

To be clear: this isn't approved by LWG yet, but I think we can be a
bit adventurous with deduction guides and add them for experimental
C++17 features. Getting more usage experience before we standardise
these things will be good, and deduction guides are very new and
untried. If we find problems we can remove them again, and will have
invaluable feedback for the standards committee.
Tim Song Jan. 30, 2017, 10:06 p.m. UTC | #3
On Mon, Jan 30, 2017 at 9:36 PM Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On 30/01/17 13:28 +0000, Jonathan Wakely wrote:
> >On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
> >>Tested on Linux-x64.
> >
> >OK, thanks.
>
> To be clear: this isn't approved by LWG yet, but I think we can be a
> bit adventurous with deduction guides and add them for experimental
> C++17 features. Getting more usage experience before we standardise
> these things will be good, and deduction guides are very new and
> untried. If we find problems we can remove them again, and will have
> invaluable feedback for the standards committee.
>

My brain compiler says that this may cause problems with

std::optional<int> o1;
std::optional o2 = o1; // wanted optional<int>, deduced optional<optional<int>>

Trunk GCC deduces optional<int>, but I don't think it implements
P0512R0 yet, which prefers explicit guides to implicit ones before
considering partial ordering. This example is very similar to the
example in https://timsong-cpp.github.io/cppwp/over.match.best#1.6.

Tim
Ville Voutilainen Jan. 30, 2017, 10:41 p.m. UTC | #4
On 31 January 2017 at 00:06, Tim Song <t.canens.cpp@gmail.com> wrote:
> On Mon, Jan 30, 2017 at 9:36 PM Jonathan Wakely <jwakely@redhat.com> wrote:
>>
>> On 30/01/17 13:28 +0000, Jonathan Wakely wrote:
>> >On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
>> >>Tested on Linux-x64.
>> >
>> >OK, thanks.
>>
>> To be clear: this isn't approved by LWG yet, but I think we can be a
>> bit adventurous with deduction guides and add them for experimental
>> C++17 features. Getting more usage experience before we standardise
>> these things will be good, and deduction guides are very new and
>> untried. If we find problems we can remove them again, and will have
>> invaluable feedback for the standards committee.
>>
>
> My brain compiler says that this may cause problems with
>
> std::optional<int> o1;
> std::optional o2 = o1; // wanted optional<int>, deduced optional<optional<int>>
>
> Trunk GCC deduces optional<int>, but I don't think it implements
> P0512R0 yet, which prefers explicit guides to implicit ones before
> considering partial ordering. This example is very similar to the
> example in https://timsong-cpp.github.io/cppwp/over.match.best#1.6.


I'll see about constraining the guide tomorrow.
Ville Voutilainen Jan. 31, 2017, 12:48 a.m. UTC | #5
On 31 January 2017 at 00:41, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 31 January 2017 at 00:06, Tim Song <t.canens.cpp@gmail.com> wrote:
>> On Mon, Jan 30, 2017 at 9:36 PM Jonathan Wakely <jwakely@redhat.com> wrote:
>>>
>>> On 30/01/17 13:28 +0000, Jonathan Wakely wrote:
>>> >On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
>>> >>Tested on Linux-x64.
>>> >
>>> >OK, thanks.
>>>
>>> To be clear: this isn't approved by LWG yet, but I think we can be a
>>> bit adventurous with deduction guides and add them for experimental
>>> C++17 features. Getting more usage experience before we standardise
>>> these things will be good, and deduction guides are very new and
>>> untried. If we find problems we can remove them again, and will have
>>> invaluable feedback for the standards committee.
>>>
>>
>> My brain compiler says that this may cause problems with
>>
>> std::optional<int> o1;
>> std::optional o2 = o1; // wanted optional<int>, deduced optional<optional<int>>
>>
>> Trunk GCC deduces optional<int>, but I don't think it implements
>> P0512R0 yet, which prefers explicit guides to implicit ones before
>> considering partial ordering. This example is very similar to the
>> example in https://timsong-cpp.github.io/cppwp/over.match.best#1.6.
>
>
> I'll see about constraining the guide tomorrow.

I don't actually need to constrain it, I could just add a guide like

template <typename _Tp> optional(optional<_Tp>) -> optional<_Tp>;

However, I'm not convinced I need to. The preference to an explicit
guide is, at least based
on that paper, a tie-breaker rule. If the copy/move constructors are
better matches than the guide,
those should be picked over a guide. Jason?
Tim Song Jan. 31, 2017, 2:25 a.m. UTC | #6
On Tue, Jan 31, 2017 at 8:48 AM Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
>
> On 31 January 2017 at 00:41, Ville Voutilainen
> <ville.voutilainen@gmail.com> wrote:
>
> I don't actually need to constrain it, I could just add a guide like
>
> template <typename _Tp> optional(optional<_Tp>) -> optional<_Tp>;
>
> However, I'm not convinced I need to. The preference to an explicit
> guide is, at least based
> on that paper, a tie-breaker rule. If the copy/move constructors are
> better matches than the guide,
> those should be picked over a guide. Jason?

Yes, but they are not "better matches". They are equally good matches
after deduction and substitution. The mechanism that selects
template<class T> void f(const optional<T>&) over template<class T>
void f(T) given an optional<int> argument is partial ordering, and
that's the last tiebreaker in the list, *after* the implicit/explicit
guide tiebreaker.
Jason Merrill Feb. 21, 2017, 8:44 p.m. UTC | #7
On Mon, Jan 30, 2017 at 4:48 PM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 31 January 2017 at 00:41, Ville Voutilainen
> <ville.voutilainen@gmail.com> wrote:
>> On 31 January 2017 at 00:06, Tim Song <t.canens.cpp@gmail.com> wrote:
>>> On Mon, Jan 30, 2017 at 9:36 PM Jonathan Wakely <jwakely@redhat.com> wrote:
>>>>
>>>> On 30/01/17 13:28 +0000, Jonathan Wakely wrote:
>>>> >On 30/01/17 13:47 +0200, Ville Voutilainen wrote:
>>>> >>Tested on Linux-x64.
>>>> >
>>>> >OK, thanks.
>>>>
>>>> To be clear: this isn't approved by LWG yet, but I think we can be a
>>>> bit adventurous with deduction guides and add them for experimental
>>>> C++17 features. Getting more usage experience before we standardise
>>>> these things will be good, and deduction guides are very new and
>>>> untried. If we find problems we can remove them again, and will have
>>>> invaluable feedback for the standards committee.
>>>>
>>>
>>> My brain compiler says that this may cause problems with
>>>
>>> std::optional<int> o1;
>>> std::optional o2 = o1; // wanted optional<int>, deduced optional<optional<int>>
>>>
>>> Trunk GCC deduces optional<int>, but I don't think it implements
>>> P0512R0 yet, which prefers explicit guides to implicit ones before
>>> considering partial ordering. This example is very similar to the
>>> example in https://timsong-cpp.github.io/cppwp/over.match.best#1.6.
>>
>>
>> I'll see about constraining the guide tomorrow.
>
> I don't actually need to constrain it, I could just add a guide like
>
> template <typename _Tp> optional(optional<_Tp>) -> optional<_Tp>;
>
> However, I'm not convinced I need to. The preference to an explicit guide is, at least based
> on that paper, a tie-breaker rule. If the copy/move constructors are better matches than the guide,
> those should be picked over a guide. Jason?

Currently G++ first tries deduction directly from the intializer like
in a call to a function template; only if that fails does it consider
deduction guides.  How to handle class deduction WRT
implicitly-declared constructors is still very much under discussion.

Jason
diff mbox

Patch

diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index 887bf9e..905bc0a 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -981,6 +981,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @}
 
+  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc b/libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc
new file mode 100644
index 0000000..59698dc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/deduction_guide.cc
@@ -0,0 +1,44 @@ 
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <optional>
+#include <type_traits>
+
+struct MoveOnly
+{
+  MoveOnly() = default;
+  MoveOnly(MoveOnly&&) {}
+  MoveOnly& operator=(MoveOnly&&) {}
+};
+
+int main()
+{
+    std::optional x = 5;
+    static_assert(std::is_same_v<decltype(x), std::optional<int>>);
+    int y = 42;
+    std::optional x2 = y;
+    static_assert(std::is_same_v<decltype(x2), std::optional<int>>);
+    const int z = 666;
+    std::optional x3 = z;
+    static_assert(std::is_same_v<decltype(x3), std::optional<int>>);
+    std::optional mo = MoveOnly();
+    static_assert(std::is_same_v<decltype(mo), std::optional<MoveOnly>>);
+    mo = MoveOnly();
+}