shared_ptr<T>'s nullptr_t constructor causes ambiguities

242 views
Skip to first unread message

Johannes Schaub

unread,
Jun 23, 2012, 3:11:47 PM6/23/12
to std-dis...@isocpp.org
Today I learned that shared_ptr<T> allows to construct an empty state not only by default initialization but also with initialization by "nullptr". However this opens the door for unfortunate ambiguities. Consider:

  void f(std::shared_ptr<string>);
  void f(std::vector<int>);

  int main() { f({0}); }

The "0" can convert to "nullptr_t" and hence to shared_ptr<string>. 

Dave Abrahams

unread,
Jun 23, 2012, 4:26:03 PM6/23/12
to std-dis...@isocpp.org
I understand why we want "0" to be convertible to nullptr_t, but can't
understand why "{0}" should have that property (which is what I see
here).

--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

alf.p.s...@gmail.com

unread,
Jun 23, 2012, 6:18:57 PM6/23/12
to std-dis...@isocpp.org

I see it as a defect, because it makes 0 and nullptr have different effects as actual argument to the shared_ptr constructor. Both msvc 10 and g++ 4.6.1 make 0 and nullptr have identical effect, so both are non-confoming. However, they chose different effects, so there is not an obvious de facto standard to rely on for resolving the problem with the official standard.
 

Johannes Schaub

unread,
Jun 24, 2012, 7:54:49 AM6/24/12
to std-dis...@isocpp.org
I understand the position that 0 be convertible to shared_ptr<T>. But I think it is better to leave it unconvertible to shared_ptr. boost::shared_ptr<> does not seem to allow it either (though I don't know whether that's merely because of lack of "nullptr_t" in C++03), and the usual recommended way to specify null pointer constants is through "nullptr". 

That {0} is allowed too is just a consequence of the rules of list initalization. I chose "{0}" in my post instead of "0" because I couldn't think of a user defined type in std:: that is implicitly convertible from 0.

Dave Abrahams

unread,
Jun 24, 2012, 11:35:01 AM6/24/12
to std-dis...@isocpp.org

on Sun Jun 24 2012, Johannes Schaub <schaub.johannes-AT-googlemail.com> wrote:

> I understand why we want "0" to be convertible to nullptr_t, but
> can't understand why "{0}" should have that property (which is
> what I see here).
>
>
>
> I understand the position that 0 be convertible to shared_ptr<T>. But
> I think it is better to leave it unconvertible to shared_ptr.
> boost::shared_ptr<> does not seem to allow it either (though I don't
> know whether that's merely because of lack of "nullptr_t" in C++03),
> and the usual recommended way to specify null pointer constants is
> through "nullptr".
>
> That {0} is allowed too is just a consequence of the rules of list
> initalization.

I figured as much. I'm suggesting maybe those rules may not be adequate
for our needs.
Reply all
Reply to author
Forward
0 new messages