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 31,835 of 33,346   
   Jonathan Thornburg to All   
   Re: boost::format vs. in-class 'static c   
   23 Jan 12 17:42:41   
   
   From: clcppm-poster@this.is.invalid   
      
   I wrote:   
   | I recently ran across an interesting problem in combining two parts of   
   | C++ that individually work beautifully:  boost::format  and in-class   
   | 'static const int' constants.   
   [[example omitted]]   
   | So, what to do if we want to use boost::format to print out (messages   
   | which include) in-class constant ints?  I can see several possible   
   | solutions:   
   |   
   | We could explicitly define the in-class constant ints outside the class   
   | declaration.  This is awkward on two grounds:   
   | * it makes the code less readable: N must then be initialized in the   
   |    definition,   
      
   Daniel Kr?gler replied   
   > This is wrong, providing the definition separately does not require to   
   > move the initializer to the point of the definition. According to   
   > [class.static.data] p3:   
   >   
   > "[..] The member shall still be defined in a namespace scope if it is   
   > odr-used (3.2) in the program and the namespace scope definition shall   
   > not contain an initializer."   
      
   My mistake -- thanks for correcting me!  That removes the major objection   
   I had to this approach.   
      
      
   [[...]]   
   | * if the class is actually a template, the definition needs to be   
   |    replicated for each instantiation of the template   
      
   > I don't know what you mean with "replicated", and I don't see a problem   
   > here for you. It is the compiler who has to ignore the multiple   
   > instantiations, not you.   
      
   I was thinking of the following slightly-more-elaboprate example,   
   where the in-class const int lives in a template class:   
      
     #include    
     #include    
     #include "boost/format.hpp"   
      
     using std::cout;   
     using boost::format;   
      
     // identity function   
     template  inline T I(T x) { return x; }   
      
     // class template containing in-class 'static const int'   
     template    
     class   foo   
             {   
     public:   
             static const int N = 42;   
             };   
      
     // explicit instantiations of class template   
     template class foo;   
     template class foo;   
     template class foo< std::complex >;   
      
     // must provide an explicit definition of N for each instantiation   
     template <> const int foo::N;   
     template <> const int foo::N;   
     template <> const int foo< std::complex >::N;   
      
     int main()   
     {   
     cout << "raw output:   N  = " <<   foo::N << "\n";   
     cout << "raw output: I(N) = " << I(foo::N) << "\n";   
     #if 0   
     cout << format("boost::format output:   N  = %d\n") %   foo::N;   
     #endif   
     cout << format("boost::format output: I(N) = %d\n") % I(foo::N);   
      
     return 0;   
     }   
      
   Here there must be an explicit definition of foo::N for *each*   
   (distinct) instantiation of the template class foo (for which we want   
   to ensure that  boost::format  printing is possible).   
      
   Alas, the above code still doesn't work if the "#if 0" is changed to   
   "#if 1": it again fails to link:   
      
   > /usr/tmp/ccBID7mW.o(.text+0x208): In function `main':   
   > /usr/local/include/boost/format/format_implementation.hpp:201: undefined   
   reference to `foo::N'   
   > collect2: ld returned 1 exit status   
      
   Since I've defined  foo::N  I don't understand why references   
   to  foo::N  are undefined.   
      
   Thanks again for your assistance,   
      
   --   
   -- "Jonathan Thornburg [remove -animal to reply]"    
     Dept of Astronomy & IUCSS, Indiana University, Bloomington, Indiana, USA   
     "Washing one's hands of the conflict between the powerful and the   
      powerless means to side with the powerful, not to be neutral."   
                                        -- quote by Freire / poster by Oxfam   
      
      
         [ 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