Rationale behind not allowing template parameters to be friends?

  • Thread starter Asfand Yar Qazi
  • Start date
A

Asfand Yar Qazi

Consider the following code:

=========================================

#include <iostream>

template<class ValueT, OwnerT>
class Restricted_Public_Variable
{
public:
typedef Restricted_Public_Variable Self;

private:
Restricted_Public_Variable()
: data()
{
}

virtual
~Restricted_Public_Variable()
{
}

Restricted_Public_Variable(const ValueT& arg)
: data(arg)
{
}

Restricted_Public_Variable(const Self& arg)
: data(arg.data)
{
}

const Self&
operator=(const ValueT& arg)
{
data = arg;
return *this;
}

friend OwnerT;

ValueT data;

public:
operator ValueT()
{
return data;
}

const ValueT&
get() const
{
return data;
}
};

class Big
{
public:
Big(int arg)
: myint(arg)
{
}

Restricted_Public_Variable<int, Big> myint;
};

int
main()
{
Big b(3);

std::cout << b.myint << std::endl; // 3

// The following is disallowed, we can
// only read the 'myint' value
// b.myint = 5;
}

=========================================

Yet the compiler (gcc 3.3.3) says:

template parameters cannot be friends

Bah foiled...

Can anybody explain why this is?
 
S

Siemel Naran

Asfand Yar Qazi said:
template<class ValueT, OwnerT>
class Restricted_Public_Variable
{
public:
typedef Restricted_Public_Variable Self;

private:
Restricted_Public_Variable()
: data()
{
}

virtual
~Restricted_Public_Variable()
{
}

Restricted_Public_Variable(const ValueT& arg)
: data(arg)
{
}

Restricted_Public_Variable(const Self& arg)
: data(arg.data)
{
}

const Self&
operator=(const ValueT& arg)
{
data = arg;
return *this;
}

Compiler generated copy constructor, operator=, destructor are fine. It
makes sense to define any of these functions anyway if you want them to be
non-inline. I usually do it for the virtual destructor only though.

friend OwnerT;

ValueT data;

It's not allowed at present. I think there was a proposal to make it legal,
but maybe I am mistaken. As a workaround you can create a public function
that returns a writable reference to data, and the function will take an
OwnerT::Restricted_Public_Variable or other class by value. But the default
constructor of this class will be private so that only members of OwnerT
will be able to create OwnerT::Restricted_Public_Variable objects.

ValueT& getdata(OwnerT::Restricted_Public_Variable) {
return data;
}



class Big
{
class Private_Restricted_Public_Variable { };
public:
Big(int arg)
: myint(arg)
{
}

Restricted_Public_Variable<int, Big> myint;
void f() { getdata(Private_Restricted_Public_Variable()) = 3; }
 
A

Asfand Yar Qazi

<snip>

Thanks both - but I think I'll use Siemel's version :) Hopefully it
works on all compilers, unlike the forms identified in the article
Jonathan linked to (although it was a very enlightening article.)

Thanks both,
Asfand Yar
 
A

Asfand Yar Qazi

Asfand said:
<snip>

Thanks both - but I think I'll use Siemel's version :) Hopefully it
works on all compilers, unlike the forms identified in the article
Jonathan linked to (although it was a very enlightening article.)

Hang on a mo Siemel... I think you've misunderstood what I was trying to
do. I'm trying to create a public variable that is publicly readable,
but only the owner can write to (similar to how Eiffel defines its
variables.)

Sorry about that, thanks anyway,
Asfand Yar
 
S

Siemel Naran

Asfand Yar Qazi said:
Hang on a mo Siemel... I think you've misunderstood what I was trying to
do. I'm trying to create a public variable that is publicly readable,
but only the owner can write to (similar to how Eiffel defines its
variables.)

Sure, you can derive publicly from Restricted_Public_Variable, so all users
can take advantage of Restricted_Public_Variable::eek:perator() which returns a
readable reference. But only users with ability to create the private class
can make use of the getdata() function which returns a writable reference.
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top