Guest User

testcase.cpp

a guest
Aug 3rd, 2017
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. // testcase.cpp
  2.  
  3. // Demonstration of a regression in developerstudio12.5 versus
  4. //   solarisstudio12.3   (no 12.4 was within reach for testing)
  5. // compileable with: CC: Sun C++ 5.9 and 5.12  as well as: GCC 3.4.6 and 5.4.0
  6. // not compileable with  CC: Studio 12.5 Sun C++ 5.14
  7.  
  8. // (1) Everything in the namespace TEST can be considered to be
  9. //   defined within the headers of a library: (The real case was
  10. //   much more complicated and involved a chain of 2 templates.)
  11.  
  12. namespace TEST {
  13.  
  14.    class Any ; // Forward declaration of class Any
  15.  
  16.  
  17.    // (2) Template class using an operator on an object of type Any:
  18.    //    that could mean either a member op, e.g.: operator<<=(X x&)
  19.    //    or a global operator<<=(Any&, X x&) defined outside any class.
  20.  
  21.    template < typename S >
  22.    struct Templ {
  23.       static inline void func(Any *p , S const & x ) {
  24.          (*p) <<= x ;
  25.       }
  26.    };
  27.  
  28.  
  29.    // (3) definition of class Any.
  30.    //   Note: the operator defined within the class is perfectly well
  31.    //   seen by the template. (in the original code this one operator
  32.    //   is on purpose declared "private" and has no implementation, in
  33.    //   order to trigger compiler or linker errors if accidentally used.)
  34.    //   Removing it may only alter the verbiage of the error, but doesn't
  35.    //   solve the problem.
  36.  
  37.    class Any {
  38.       private:
  39.          void operator<<= (unsigned char);
  40.    };
  41. }
  42.  
  43.  
  44. // (4) The following code would appear in user code that included the
  45. //    above declarations through a set of header files, so this
  46. //    would be foreign code from TEST's point of view.
  47. //
  48. //   The following global operator is NOT "seen" by the template.
  49. //   Instead, when trying to resolve it within Templ, the compiler
  50. //   falls back to the private one taking "unsigned char" and
  51. //   complains as it is indeed not accessible.
  52. //
  53. //   With this simple second argument type "unsigned" the operator
  54. //   prototype could in principle be moved before (2). Then the
  55. //   template would in fact see and use it; however moving it right
  56. //   after (2) still shows the problem.
  57.  
  58. void operator<<= ( TEST::Any&, unsigned);
  59.  
  60.  
  61. // some more user declarations:
  62. namespace USER {
  63.    struct MyClass {
  64.       struct MyNest; // declare a nested class
  65.       enum   MyEnum { A, B, C }; // declare an enum
  66.    
  67.       // a method that will use the template
  68.       void test();
  69.    };
  70. }
  71.  
  72. // (5) another two global operators NOT "seen" by the template.
  73. //   It is not possible in C++ to pre-declare MyClass::MyNest
  74. //   or MyClass::MyEnum before MyClass itself is defined.
  75. //   But exactly that would be necessary to be able to pre-
  76. //   declare these operator-overloads already before (2)
  77. //   in order to make them visible to the template.
  78.  
  79. void operator<<= ( TEST::Any&, const USER::MyClass::MyNest &);
  80. void operator<<= ( TEST::Any&, USER::MyClass::MyEnum);
  81.  
  82. // (6) now use the template on these types, for which by now an
  83. //  overload of the operator has been declared.
  84.  
  85. void USER::MyClass::test() {
  86.    TEST::Any *a = 0; MyNest *mn = 0; // 0 doesn't matter here.
  87.  
  88.    // Here, the compiler tries to use the private operator for unsigned char.
  89.    // Error: TEST::Any::operator<<=(unsigned char) is not accessible from ...
  90.    TEST::Templ<unsigned>::func( a, 42U );
  91.  
  92.    // Here, the compiler just cannot find anything suitable at all.
  93.    // Error: The operation "TEST::Any<<= const USER::MyClass::MyNest" is illegal.
  94.    TEST::Templ<MyClass::MyNest>::func( a, *mn );
  95.  
  96.    // Here, the compiler tries to use the private operator for unsigned char.
  97.    // Error: Error: TEST::Any::operator<<=(unsigned char) is not accessible from ...
  98.    TEST::Templ<MyClass::MyEnum>::func( a, B );
  99. }
  100.  
  101. // compile with  CC -c testcase.cpp
Advertisement
Add Comment
Please, Sign In to add comment