Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Parameter type deduction with constructors

203 views
Skip to first unread message

woodb...@gmail.com

unread,
Dec 24, 2016, 7:55:02 PM12/24/16
to
Previously I had this line:
::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));

After getting C++ 2014 compilers, I wrote it like this:
auto request=::std::make_unique<cmw_request>(localbuf);

I was watching Mark Isaacson's talk here:
https://www.youtube.com/watch?v=-ctgSbEfRxU
. (You can watch it from https://duckduckgo.com if you want.)
He talks about parameter type deduction for constructors
shortly after the two minute mark.

So I'm wondering if this is going to be valid C++ 2017 code:

::std::unique_ptr<cmw_request> request(localbuf);

It doesn't compile with clang++ 3.8.1.

And I was trying to find an online C++ compiler that has
support for C++ 2017, but only found support for C++ 2014
and earlier. Could someone point me to a site that has that?
Thanks in advance.


Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

woodb...@gmail.com

unread,
Dec 24, 2016, 8:34:21 PM12/24/16
to
On Saturday, December 24, 2016 at 6:55:02 PM UTC-6, woodb...@gmail.com wrote:
> Previously I had this line:
> ::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));
>
> After getting C++ 2014 compilers, I wrote it like this:
> auto request=::std::make_unique<cmw_request>(localbuf);
>
> I was watching Mark Isaacson's talk here:
> https://www.youtube.com/watch?v=-ctgSbEfRxU
> . (You can watch it from https://duckduckgo.com if you want.)
> He talks about parameter type deduction for constructors
> shortly after the two minute mark.
>
> So I'm wondering if this is going to be valid C++ 2017 code:
>
> ::std::unique_ptr<cmw_request> request(localbuf);
>

Or maybe it should be:

::std::unique_ptr request(cmw_request(localbuf));

or

::std::unique_ptr request(::new cmw_request(localbuf));

?

Those don't compile here either.
::std::unique_ptr request(::new cmw_request(localbuf));
> It doesn't compile with clang++ 3.8.1.
>
>

woodb...@gmail.com

unread,
Dec 24, 2016, 10:03:24 PM12/24/16
to
On Saturday, December 24, 2016 at 6:55:02 PM UTC-6, woodb...@gmail.com wrote:
I checked Compiler Explorer now and it has more up to date
compilers.

Ian Collins

unread,
Dec 24, 2016, 10:48:33 PM12/24/16
to
On 12/25/16 01:54 PM, woodb...@gmail.com wrote:
> Previously I had this line:
> ::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));

I can see some (very week) justification for the superfluous colons
before std, but new?

--
Ian

woodb...@gmail.com

unread,
Dec 28, 2016, 5:30:05 PM12/28/16
to
On Saturday, December 24, 2016 at 7:34:21 PM UTC-6, woodb...@gmail.com wrote:
> On Saturday, December 24, 2016 at 6:55:02 PM UTC-6, woodb...@gmail.com wrote:
> > Previously I had this line:
> > ::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));
> >
> > After getting C++ 2014 compilers, I wrote it like this:
> > auto request=::std::make_unique<cmw_request>(localbuf);
> >
> > I was watching Mark Isaacson's talk here:
> > https://www.youtube.com/watch?v=-ctgSbEfRxU
> > . (You can watch it from https://duckduckgo.com if you want.)
> > He talks about parameter type deduction for constructors
> > shortly after the two minute mark.
> >
> > So I'm wondering if this is going to be valid C++ 2017 code:
> >
> > ::std::unique_ptr<cmw_request> request(localbuf);
> >
>
> Or maybe it should be:
>
> ::std::unique_ptr request(cmw_request(localbuf));
>
> or
>
> ::std::unique_ptr request(::new cmw_request(localbuf));
>
> ?
>
> Those don't compile here either.

I think the right answer is probably one of the last
two that I posted, but I've yet to find a compiler that
supports this.

Alf P. Steinbach

unread,
Dec 28, 2016, 6:34:28 PM12/28/16
to
On 25.12.2016 01:54, woodb...@gmail.com wrote:
> Previously I had this line:
> ::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));
>
> After getting C++ 2014 compilers, I wrote it like this:
> auto request=::std::make_unique<cmw_request>(localbuf);
>

I haven't used the feature, but I think if `localbuf` is not a pointer
but something passed by reference, you need to use `std::ref`.

And in general, I'd just make a factory function.


Cheers!,

- Alf


Alf P. Steinbach

unread,
Dec 28, 2016, 6:37:42 PM12/28/16
to
It avoids invoking a class-specific override of the allocation function.

It can be bug because if `std::default_delete` isn't specialized for
this class, it will use an ordinary delete expression that invokes a
class specific deallocation function if such exists.

But then, if `std::default_delete` isn't specialized and the class
overrides allocation and deallocation, then this qualification is a sort
of dirty workaround: not benefiting from the custom allocator, but at
least not invoking Undefined Behavior.


Cheers!,

- Alf

woodb...@gmail.com

unread,
Dec 28, 2016, 9:23:35 PM12/28/16
to
On Wednesday, December 28, 2016 at 5:34:28 PM UTC-6, Alf P. Steinbach wrote:
> On 25.12.2016 01:54, woodb...@gmail.com wrote:
> > Previously I had this line:
> > ::std::unique_ptr<cmw_request> request(::new cmw_request(localbuf));
> >
> > After getting C++ 2014 compilers, I wrote it like this:
> > auto request=::std::make_unique<cmw_request>(localbuf);
> >
>
> I haven't used the feature, but I think if `localbuf` is not a pointer
> but something passed by reference, you need to use `std::ref`.

What feature do you mean? localbuf isn't a pointer. I've
not gotten any compiler warnings or run time errors from that
line. It is currently line 257 in this file:

https://github.com/woodbrian/onwards/blob/master/cmwAmbassador.cc

>
> And in general, I'd just make a factory function.
>

You may have missed what I was asking about. There's a new way
to write that line without using make_unique. This has more info:

http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4471.html

It says: Creating “make functions” like make_tuple is confusing,
artificial, extra boilerplate, and inconsistent with how non-template
classes are constructed.

Unfortunately, none of the examples they mention are of
std::unique_ptr.


Brian
Ebenezer Enterprises - Enjoy programming again.
http://webEbenezer.net

woodb...@gmail.com

unread,
Jan 17, 2017, 12:51:44 PM1/17/17
to
This is one of many old topics that I'd like to find out
more about.


Brian
Ebenezer Enterprises
http://webEbenezer.net

Öö Tiib

unread,
Jan 19, 2017, 2:28:36 AM1/19/17
to
Why you are interested specially about smart pointers?
You won't get it much shorter than that

auto r = std::make_unique<R>(l);

The idea that factories are bad thing is perhaps personal position of
professor Michael Spertus. When it matters to where and how and if
something is created (or reused from lazy cache) then the factories are used
a lot and it is not only in C++. The smart pointer factories get rid of
usage of naked 'new' and on case of 'std::make_shared' it also manages
memory better than constructor can.

There may be also is a technical difficulty. std::unique_ptr has AFAIK about 7
constructors overloads some of what are templates themselves. So deducing
two levels of template arguments from overloaded constructor call may
mean some quite fragile and confusing heuristics.

woodb...@gmail.com

unread,
Jan 19, 2017, 2:48:16 PM1/19/17
to
I already have this line in my program:

::std::queue<::std::unique_ptr<cmw_request>> pendingTransactions;

In my opinion it would be better to have this:

::std::unique_ptr request(::new cmw_request(localbuf));

than this:

auto request=::std::make_unique<cmw_request>(localbuf);

Make_unique and the knowledge of what it is/does would no
longer be needed.


> The idea that factories are bad thing is perhaps personal position of
> professor Michael Spertus. When it matters to where and how and if
> something is created (or reused from lazy cache) then the factories are used
> a lot and it is not only in C++. The smart pointer factories get rid of
> usage of naked 'new' and on case of 'std::make_shared' it also manages
> memory better than constructor can.
>

He proposed it, but the idea has apparently been accepted
by those on the committee. I'm fine with the exposed 'new'.


> There may be also is a technical difficulty. std::unique_ptr has AFAIK about 7
> constructors overloads some of what are templates themselves. So deducing
> two levels of template arguments from overloaded constructor call may
> mean some quite fragile and confusing heuristics.

One bit of good news is that, according to this,
http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr

one of those constructors is going away as of C++ 2017. And it
is one of the two template constructors so that may help.
Thanks for your comments.

woodb...@gmail.com

unread,
Jan 21, 2017, 8:23:10 PM1/21/17
to
I've gotten gcc 7.0 installed now and have tried 2 different ways
to get this working. Neither of them has worked.

One way has this:

::std::unique_ptr request(cmw_request(localbuf));

As line 302 in this file
https://github.com/Ebenezer-group/onwards/blob/master/cmwAmbassador.cc



g++7 -o cmwAmbassador -std=c++1z -O2 -Wshadow -Wundef -Wreorder -W -Wall -Wextra -s cmwAmbassador.cc libhome.a
cmwAmbassador.cc: In constructor 'cmwAmbassador::cmwAmbassador(const char*)':
cmwAmbassador.cc:302:9: error: deduced class type 'unique_ptr' in function return type
::std::unique_ptr request(cmw_request(localbuf));
^~
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:153:11: note: 'template<class _Tp, class _Dp> class std::unique_ptr' declared here
class unique_ptr
^~~~~~~~~~
cmwAmbassador.cc:303:59: error: use of 'unique_ptr request(cmw_request)' before deduction of 'auto'
middle_messages_back::Marshal(cmwSendbuf,Generate,request->accountNbr
^~~~~~~
cmwAmbassador.cc:304:58: error: use of 'unique_ptr request(cmw_request)' before deduction of 'auto'
,request_generator(request->filename),500000);
^~~~~~~
cmwAmbassador.cc:305:9: error: use of 'unique_ptr request(cmw_request)' before deduction of 'auto'
request->latest_update=current_updatedtime;
^~~~~~~
cmwAmbassador.cc:306:9: error: use of 'unique_ptr request(cmw_request)' before deduction of 'auto'
request->front_tier=front;
^~~~~~~
cmwAmbassador.cc:307:46: error: use of 'unique_ptr request(cmw_request)' before deduction of 'auto'
pendingTransactions.push(::std::move(request));
^~~~~~~
*** Error code 1


And the other way is with a 'new' added:

::std::unique_ptr request(new cmw_request(localbuf));

g++7 -o cmwAmbassador -std=c++1z -O2 -Wshadow -Wundef -Wreorder -W -Wall -Wextra -s cmwAmbassador.cc libhome.a
cmwAmbassador.cc: In constructor 'cmwAmbassador::cmwAmbassador(const char*)':
cmwAmbassador.cc:302:60: error: no matching function for call to 'std::unique_ptr(cmw_request*)'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:376:7: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:376:7: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: mismatched types 'const std::unique_ptr<_Tp, _Dp>' and 'cmw_request*'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:84:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/backward/auto_ptr.h:326:5: note: candidate: template<class _Tp, class _Dp, class _Up, class> std::unique_ptr(std::auto_ptr<_Up>&&)-> std::unique_ptr<_Tp, _Dp>
unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept
^~~~~~~~~~~~~~~~~~~~
/usr/local/lib/gcc7/include/c++/backward/auto_ptr.h:326:5: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: mismatched types 'std::auto_ptr<_Up>' and 'cmw_request*'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:240:2: note: candidate: template<class _Tp, class _Dp, class _Up, class _Ep, class> std::unique_ptr(std::unique_ptr<_Up, _Ep>&&)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:240:2: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: mismatched types 'std::unique_ptr<_Up, _Ep>' and 'cmw_request*'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:226:7: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(std::unique_ptr<_Tp, _Dp>&&)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(unique_ptr&& __u) noexcept
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:226:7: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: mismatched types 'std::unique_ptr<_Tp, _Dp>' and 'cmw_request*'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:221:17: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(std::nullptr_t)-> std::unique_ptr<_Tp, _Dp>
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:221:17: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: couldn't deduce template parameter '_Tp'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:214:7: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::remove_reference<_To>::type&&)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(pointer __p,
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:214:7: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: candidate expects 2 arguments, 1 provided
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:202:7: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(pointer __p,
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:202:7: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: candidate expects 2 arguments, 1 provided
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:190:7: note: candidate: template<class _Tp, class _Dp> std::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer)-> std::unique_ptr<_Tp, _Dp>
unique_ptr(pointer __p) noexcept
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:190:7: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: couldn't deduce template parameter '_Tp'
::std::unique_ptr request(new cmw_request(localbuf));
^
In file included from /usr/local/lib/gcc7/include/c++/memory:80:0,
from cmwAmbassador.cc:28:
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:178:17: note: candidate: template<class _Tp, class _Dp> std::unique_ptr()-> std::unique_ptr<_Tp, _Dp>
constexpr unique_ptr() noexcept
^~~~~~~~~~
/usr/local/lib/gcc7/include/c++/bits/unique_ptr.h:178:17: note: template argument deduction/substitution failed:
cmwAmbassador.cc:302:60: note: candidate expects 0 arguments, 1 provided
::std::unique_ptr request(new cmw_request(localbuf));
^
*** Error code 1


I'd guess the approach with the 'new' is more correct than the
first approach, but not 100% sure. I'm not sure if there's a
third approach that I'm missing or if the compiler at fault.

woodb...@gmail.com

unread,
Jan 21, 2017, 8:59:18 PM1/21/17
to
Now I've tried

::std::unique_ptr request{cmw_request(localbuf)};

and

::std::unique_ptr request{new cmw_request(localbuf)};

Not 100% sure of this, but the first one may have different
output than when using parens. And the second one has the
same output regardless of braces or parens. It's a lot of
output and I might be getting something confused. I also
noticed how this constructor

template< class U >
unique_ptr( auto_ptr<U>&& u ); // (7) (until C++17)

was being considered. This page:
http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr

says that constructor is valid until C++17. Is there something
other than -std=c++1z I should use to get C++ 2017?

woodb...@gmail.com

unread,
Jan 29, 2017, 10:24:21 PM1/29/17
to
On Thursday, January 19, 2017 at 1:28:36 AM UTC-6, Öö Tiib wrote:
>
> Why you are interested specially about smart pointers?
> You won't get it much shorter than that
>
> auto r = std::make_unique<R>(l);
>
> The idea that factories are bad thing is perhaps personal position of
> professor Michael Spertus. When it matters to where and how and if
> something is created (or reused from lazy cache) then the factories are used
> a lot and it is not only in C++. The smart pointer factories get rid of
> usage of naked 'new' and on case of 'std::make_shared' it also manages
> memory better than constructor can.
>
> There may be also is a technical difficulty. std::unique_ptr has AFAIK about 7
> constructors overloads some of what are templates themselves. So deducing
> two levels of template arguments from overloaded constructor call may
> mean some quite fragile and confusing heuristics.

I asked professor Spertus about this and he came up with this:

https://github.com/mspertus/p0433/commit/9e4643943eeee39b2cb4873026dad381d58cd50c

Using that, my program compiles and runs fine.
0 new messages