Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // testcase.cpp
- // Demonstration of a regression in developerstudio12.5 versus
- // solarisstudio12.3 (no 12.4 was within reach for testing)
- // compileable with: CC: Sun C++ 5.9 and 5.12 as well as: GCC 3.4.6 and 5.4.0
- // not compileable with CC: Studio 12.5 Sun C++ 5.14
- // (1) Everything in the namespace TEST can be considered to be
- // defined within the headers of a library: (The real case was
- // much more complicated and involved a chain of 2 templates.)
- namespace TEST {
- class Any ; // Forward declaration of class Any
- // (2) Template class using an operator on an object of type Any:
- // that could mean either a member op, e.g.: operator<<=(X x&)
- // or a global operator<<=(Any&, X x&) defined outside any class.
- template < typename S >
- struct Templ {
- static inline void func(Any *p , S const & x ) {
- (*p) <<= x ;
- }
- };
- // (3) definition of class Any.
- // Note: the operator defined within the class is perfectly well
- // seen by the template. (in the original code this one operator
- // is on purpose declared "private" and has no implementation, in
- // order to trigger compiler or linker errors if accidentally used.)
- // Removing it may only alter the verbiage of the error, but doesn't
- // solve the problem.
- class Any {
- private:
- void operator<<= (unsigned char);
- };
- }
- // (4) The following code would appear in user code that included the
- // above declarations through a set of header files, so this
- // would be foreign code from TEST's point of view.
- //
- // The following global operator is NOT "seen" by the template.
- // Instead, when trying to resolve it within Templ, the compiler
- // falls back to the private one taking "unsigned char" and
- // complains as it is indeed not accessible.
- //
- // With this simple second argument type "unsigned" the operator
- // prototype could in principle be moved before (2). Then the
- // template would in fact see and use it; however moving it right
- // after (2) still shows the problem.
- void operator<<= ( TEST::Any&, unsigned);
- // some more user declarations:
- namespace USER {
- struct MyClass {
- struct MyNest; // declare a nested class
- enum MyEnum { A, B, C }; // declare an enum
- // a method that will use the template
- void test();
- };
- }
- // (5) another two global operators NOT "seen" by the template.
- // It is not possible in C++ to pre-declare MyClass::MyNest
- // or MyClass::MyEnum before MyClass itself is defined.
- // But exactly that would be necessary to be able to pre-
- // declare these operator-overloads already before (2)
- // in order to make them visible to the template.
- void operator<<= ( TEST::Any&, const USER::MyClass::MyNest &);
- void operator<<= ( TEST::Any&, USER::MyClass::MyEnum);
- // (6) now use the template on these types, for which by now an
- // overload of the operator has been declared.
- void USER::MyClass::test() {
- TEST::Any *a = 0; MyNest *mn = 0; // 0 doesn't matter here.
- // Here, the compiler tries to use the private operator for unsigned char.
- // Error: TEST::Any::operator<<=(unsigned char) is not accessible from ...
- TEST::Templ<unsigned>::func( a, 42U );
- // Here, the compiler just cannot find anything suitable at all.
- // Error: The operation "TEST::Any<<= const USER::MyClass::MyNest" is illegal.
- TEST::Templ<MyClass::MyNest>::func( a, *mn );
- // Here, the compiler tries to use the private operator for unsigned char.
- // Error: Error: TEST::Any::operator<<=(unsigned char) is not accessible from ...
- TEST::Templ<MyClass::MyEnum>::func( a, B );
- }
- // compile with CC -c testcase.cpp
Advertisement
Add Comment
Please, Sign In to add comment