Friend declaration not accepted by MSVC

A

Alf P. Steinbach

In the code below the commented friend declaration is not accepted by MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> // CPPX_IS_OVERRIDE_OFxxx

#include <assert.h>
#include <memory>


namespace progrock{ namespace cppx{

//TODO: Implement for real.

template< class T > class ZPtr;


namespace zptr{ class Referent; class Callback; }

class ZPtrMicrosoftVisualCppWorkaround
{
template< class T > friend class ZPtr;
private:
static void deleteSelfNoCallback( zptr::Referent& r );

template< class T >
static T* create( zptr::Callback& aCallback )
{ return new T( aCallback ); }

template< class T, class A1 >
static T* create( zptr::Callback& aCallback, A1 const& a1 )
{ return new T( aCallback, a1 ); }

template< class T, class A1, class A2 >
static T* create( zptr::Callback& aCallback, A1 const& a1, A2 const& a2 )
{ return new T( aCallback, a1, a2 ); }

template< class T, class A1, class A2, class A3 >
static T* create( zptr::Callback& aCallback, A1 const& a1, A2 const&
a2, A3 const& a3 )
{ return new T( aCallback, a1, a2, a3 ); }
};


namespace zptr {
class XThrower
{
public:
typedef std::auto_ptr<XThrower> AutoPtr;

virtual ~XThrower() {}

virtual bool throwX() const
{
return cppx::throwX( "cppx::ZPtr: referent has been destroyed" );
}
};

class Callback
{
public:
virtual ~Callback() {}
virtual void destroyAnyCompleteMeAndSetAccessX( XThrower::AutoPtr )
= 0;
};

class Referent
{
//template< class T > friend class cppx::ZPtr;
friend class ZPtrMicrosoftVisualCppWorkaround; // MSVC 7.1 can't
handle the direct friend.
typedef Referent ThisClass;

private:
Callback* myCallback;

Referent( ThisClass const& ); // No such.
ThisClass& operator=( ThisClass const& ); // No such.

void deleteSelfNoCallback()
{
delete this;
}

static void* operator new( size_t nBytes )
{
return ::new char[nBytes];
}

static void operator delete( void* p )
{
::delete[] static_cast<char*>( p );
}

protected:
virtual ~Referent() {}

template< class ExceptionType >
void handleUnrecoverableFailure(
ExceptionType const& x,
XThrower::AutoPtr xThrower = XThrower::AutoPtr( new
XThrower )
)
{
myCallback->destroyAnyCompleteMeAndSetAccessX( xThrower );
throw x;
}

public:
Referent( Callback& aCallback ): myCallback( &aCallback ) {}
};


enum DefaultConstructed {};
} // namespace zptr


inline void ZPtrMicrosoftVisualCppWorkaround::deleteSelfNoCallback(
zptr::Referent& r )
{
r.deleteSelfNoCallback();
}


template< typename T >
class ZPtr
: private zptr::Callback
{
typedef ZPtr ThisClass;

private:
T* myReferent; // 0 while the T constructs.
zptr::XThrower::AutoPtr myXAction;

ZPtr( ThisClass const& ); // No such.
ThisClass& operator=( ThisClass const& ); // No such.

void deleteReferent()
{
if( myReferent == 0 ) { return; }

try
{
ZPtrMicrosoftVisualCppWorkaround::deleteSelfNoCallback(
*myReferent );
}
catch( ... )
{
assert( "cppx::ZPtr: referent threw exception when deleted" &&
false );
}
myReferent = 0;
}

virtual void destroyAnyCompleteMeAndSetAccessX( zptr::XThrower::AutoPtr
xThrower )
{
CPPX_IS_OVERRIDE_OF_1ARG(
zptr::Callback::destroyAnyCompleteMeAndSetAccessX, xThrower );
assert( xThrower.get() != 0 );
assert( myXAction.get() == 0 );

deleteReferent();
myXAction = xThrower;
}

public:
ZPtr( zptr::DefaultConstructed )
: myReferent( 0 )
{
myReferent = ZPtrMicrosoftVisualCppWorkaround::create<T>( *this );
}

template< class A1 >
ZPtr( A1 const& a1 )
: myReferent( 0 )
{
myReferent = ZPtrMicrosoftVisualCppWorkaround::create<T>( *this, a1 );
}

template< class A1, class A2 >
ZPtr( A1 const& a1, A2 const& a2 )
: myReferent( 0 )
{
myReferent = ZPtrMicrosoftVisualCppWorkaround::create<T>( *this,
a1, a2 );
}

template< class A1, class A2, class A3 >
ZPtr( A1 const& a1, A2 const& a2, A3 const a3 )
: myReferent( 0 )
{
myReferent = ZPtrMicrosoftVisualCppWorkaround::create<T>( *this,
a1, a2, a3 );
}

~ZPtr()
{
deleteReferent();
}

bool isVoid() const
{
return (myReferent == 0);
}

void throwIfVoid() const
{
if( isVoid() )
{
assert( myXAction.get() != 0 );
myXAction->throwX();
assert( "Execution should never reach this point." && 0 );
}
}

T* operator->() const
{
throwIfVoid();
return myReferent;
}
};

}} // namespace progrock::cppx

#endif
</code>


I wonder if there's any better workaround than the kludge shown?

Also, is there a problem with this friend declaration with any other
compiler/version (the same kind of declaration worked fine with g++ and Comeau)?


Cheers, & TIA.,

- Alf
 
V

Victor Bazarov

Alf said:
In the code below the commented friend declaration is not accepted by
MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> // CPPX_IS_OVERRIDE_OFxxx
[..]

FAQ 5.8.
#endif
</code>


I wonder if there's any better workaround than the kludge shown?

How about switching to Visual C++ 2008? Their express edition is free,
don't you know?
Also, is there a problem with this friend declaration with any other
compiler/version (the same kind of declaration worked fine with g++ and
Comeau)?

V
 
A

Alf P. Steinbach

* Victor Bazarov:
Alf said:
In the code below the commented friend declaration is not accepted by
MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> // CPPX_IS_OVERRIDE_OFxxx
[..]

FAQ 5.8.

I hope you're joking.

How about switching to Visual C++ 2008? Their express edition is free,
don't you know?

Don't you know that I know that?


Anyways, I solved the problem by replacing

namespace zptr {
}

with

struct zptr {
};

which made the Microsoft compiler happy, and also better supports use in
classes. :)


Cheers,

- Alf
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:
Alf said:
In the code below the commented friend declaration is not accepted by
MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> //
CPPX_IS_OVERRIDE_OFxxx
[..]

FAQ 5.8.

I hope you're joking.

No, I wasn't. If you wanted help about the code that doesn't compile,
why didn't you provide a short *compilable* version of it? Too busy or
too lazy to remove the irrelevant portions? Now, who's joking?
Don't you know that I know that?

I didn't know, but I suspected. That's why I wrote "don't you know".
You didn't answer the question though. Whatever.
Anyways, I solved the problem by replacing

namespace zptr {
}

with

struct zptr {
};

which made the Microsoft compiler happy, and also better supports use in
classes. :)

Sounds good.

V
 
A

Alf P. Steinbach

* Victor Bazarov:
Alf said:
* Victor Bazarov:
Alf P. Steinbach wrote:
In the code below the commented friend declaration is not accepted
by MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> //
CPPX_IS_OVERRIDE_OFxxx
[..]

FAQ 5.8.

I hope you're joking.

No, I wasn't. If you wanted help about the code that doesn't compile,
why didn't you provide a short *compilable* version of it? Too busy or
too lazy to remove the irrelevant portions? Now, who's joking?

Compared to copying and pasting the code in your editor, the work of writing a
throwX function, like

void throwX( char const s[] ) { throw std::runtime_error( s ); }

is really insignificant.

And ditto for the macro, for the purposes of compiling.

I wouldn't want help from anyone not managing or understanding that.

I'm sure you'd manage it, which is why I enquired whether you was joking.


Cheers,

- Alf
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:
Alf said:
* Victor Bazarov:
Alf P. Steinbach wrote:
In the code below the commented friend declaration is not accepted
by MSVC 7.1.


<code>
// Copyright (c) Alf P. Steinbach, 2009.
#ifndef PROGROCK_CPPX_POINTERS_ZPTR_H
#define PROGROCK_CPPX_POINTERS_ZPTR_H
// #include <progrock/cppx/pointers/ZPtr.h>

#include <progrock/cppx/no_sillywarnings_please.h>

#include <progrock/cppx/exception_util.h> // throwX
#include <progrock/cppx/static_assert.h> //
CPPX_IS_OVERRIDE_OFxxx
[..]

FAQ 5.8.

I hope you're joking.

No, I wasn't. If you wanted help about the code that doesn't compile,
why didn't you provide a short *compilable* version of it? Too busy
or too lazy to remove the irrelevant portions? Now, who's joking?

Compared to copying and pasting the code in your editor, the work of
writing a throwX function, like

void throwX( char const s[] ) { throw std::runtime_error( s ); }

is really insignificant.

And ditto for the macro, for the purposes of compiling.

I wouldn't want help from anyone not managing or understanding that.

I'm sure you'd manage it, which is why I enquired whether you was joking.

Don't know what fly crawled up your nose today, Alf, but I don't even
read past the inclusion of the headers names of which I don't recognize.
If you don't want help "from anyone not managing", then I'm not
managing, and you don't want my help.

Why do you think you should be treated differently than anybody else
here (by me or by anybody else)? Slack is usually cut to people when
there is slack to be cut. I *don't have time* to fiddle with your code
to make it compile to verify your claim of its being non-compilable.

I guess you were able to manage without any help, though (judging how
quickly you found a solution). Happy for you.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top