home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,992 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to DeMarcus   
   Re: What does null mean?   
   22 Apr 13 15:48:09   
   
   From: daniel.kruegler@googlemail.com   
      
   On 2013-04-22 00:48, DeMarcus wrote:   
   > If you read this code, what do you think it does?   
   >   
   > CameraMan cm( nullptr );   
      
   I would guess that CameraMan is a pointer or PointerLike (whatever the   
   latter means in detail).   
      
   > It could mean anything, right?   
      
   In theory: Yes. In practice: I hope not.   
      
   I cannot prevent any programmer to assign a special funny/obscure   
   meaning to what it means that some (user-defined) type CameraMan is   
   initialized by the std::nullptr_t value. I would *hope* that this type   
   is indeed something that is related to (smart-)pointers. I would still   
   not know yet whether it means that CameraMan *is* a pointer-like type or   
   whether it has to be constructed with a pointer-like type (for whatever   
   reasons).   
      
   > const struct BadAngleType {} BAD_ANGLE;   
   > typedef NullNameAdapter AnglePtrNNA;   
   >   
   > class CameraMan   
   > {   
   > public:   
   >    CameraMan( AnglePtrNNA angle ) : angle_(angle) {}   
   >   
   > private:   
   >    int* angle_;   
   > };   
   >   
   > int main()   
   > {   
   >    int* anglep = new int( 180 );   
   >    CameraMan a( anglep );   
   >    CameraMan b( BAD_ANGLE );   
   >    CameraMan c( nullptr ); // Won't compile. Good!   
   >   
   >    return 0;   
   > }   
   >   
   > I almost got it to work on a general basis. The only thing I didn't   
   > manage to solve was the situation if you replace int* with   
   > std::unique_ptr. (If anyone feels tempted to solve it I would be   
   > delighted)   
      
   It depends what you mean with "manage to solve". Since std::unique_ptr   
   is movable but not copyable, it means that you have to provide rvalues   
   instead of lvalues in situations of assignment or construction. And   
   obviously the container type (such as CameraMan) would be move-only as   
   well. If you mean, that your adapted code using your NullNameAdapter   
   template still does not compile, when you have replaced all occurrences   
   of int* by std::unique_ptr *plus* the necessary additions of   
   std::move at the appropriate places, you may consider to replace your member   
      
     // Conversion operator to be able to return the type   
     // easily.   
     operator T&() { return t_; }   
      
   by   
      
     // Conversion operator to be able to return the type   
     // easily.   
     operator T&() & { return t_; }   
     operator T&&() && { return std::move(t_); }   
      
   to provide move-only support (in regard to the hosted type T) to   
   NullNameAdapter.   
      
   > In C++ Coding Standards by Sutter & Alexandrescu there is the   
   > recommendation Item 17 - Avoid magic numbers. It says that instead of   
   > using 3.1415 explcitly in the code you should make a symbolic constant   
   > out of it, like this.   
   > const double PI = 3.1415;   
   >   
   > My question is; would you all agree that nullptr is a magic number that   
   > always should be replaced with a label like the following?   
   > const std::nullptr_t BAD_ANGLE = nullptr;   
      
   I wouldn't recommend this as a general guide-line. Instead I would   
   recommend to think twice if you consider to give values of type   
   std::nullptr_t a very different meaning from initializing a pointer-like   
   thingee. It is unclear to me, why your NullNameAdapter gives   
   std::nullptr_t values such a special meaning. The hidden assumption is,   
   that all values *different* from std::nullptr_t would be "reasonable"   
   initialization values. I see no fundamental reason for this assumption.   
   So what about wrapping boost::optional in your adapter and reflecting   
   upon whether boost::none_t should be allowed as an initializer? Why   
   would this be "good" or "bad"?   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca