Jump to content
  • Advertisement
Sign in to follow this  
Rattrap

Problem with a templated overloaded friend operator

This topic is 4134 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a tempalted serialization class that is basically just a deque that tries to uniformally store data (aka handles endian conversions, etc). I am trying to make it friends will any class that follows the "operator <<" pattern.
//	Stripped down version of my code.  Compiled in Visual Studio 2005 SP1
template <typename ThreadingPolicy = KS::Threads::SingleThreadModel>
class CSerialize
{
public:
	template <typename T>
	friend CSerialize<ThreadingPolicy>& operator << (CSerialize<ThreadingPolicy>& lhs, const T& rhs);

private:
	KS::deque<char>	m_Deque;
	//Policy based mutex that is part of the ThreadingPolicy template
	mutable typename ThreadingPolicy::Mutex	m_Mutex;
};

template <typename Storage = KS::ptr_t, typename ThreadModel = KS::Threads::SingleThreadModel>
class CBigVariableUnsignedInteger
{
public:
	template <typename AnyThreadingPolicySerial>
	friend KS::IO::CSerialize<AnyThreadingPolicySerial>& operator << (KS::IO::CSerialize<AnyThreadingPolicySerial>& lhs, const KS::Math::BigIntegers::CBigVariableUnsignedInteger& rhs)
	{
		lhs.m_Mutex.lock();
		lhs.m_Mutex.unlock();

		return lhs;
	}
};

int main()
{
	CSerialize<>					cser;
	BigIntegers::CBigVariableUnsignedInteger<>	bigint;

	cser << bigint;

	return 0;
}




Error 1 error C2248: 'KS::IO::CSerialize<ThreadingPolicy>::m_Mutex' : cannot access private member declared in class 'KS::IO::CSerialize<ThreadingPolicy>' e:\programming\ksframework\math\bigintegers\cbigvariableunsignedinteger.h 48 Error 2 error C2248: 'KS::IO::CSerialize<ThreadingPolicy>::m_Mutex' : cannot access private member declared in class 'KS::IO::CSerialize<ThreadingPolicy>' e:\programming\ksframework\math\bigintegers\cbigvariableunsignedinteger.h 49 I was thinking that the templated version of friend "operator <<" in CSerialize should have been a catch all for anything that followed the same pattern, which it doesn't seem to be doing. (I have tried 2 difference versions of "operator <<" for the bigint class, one that was inside the class and one outside.) Is my logic just wrong for the friend template decleration, or is it my syntax?

Share this post


Link to post
Share on other sites
Advertisement
friend means that you are exposing the private data members of a class to whatever you're delcaring as a friend.

In your example, you're saying that CBigVariableUnsignedInteger's private data members should be exposed to certain method signatures.

CBigVariableUnsignedInteger does not have access to CSerialize<T>'s private m_Mutex data member.

Share this post


Link to post
Share on other sites
I think you've got some kind of namespace name scoping issue, since when I reconstructed your example, it built nicely in this form:


struct SingleThreadModel
{
class Mutex
{
public:
void lock() {}
void unlock() {}
};
};

typedef int *ptr_t;

template <typename ThreadingPolicy = SingleThreadModel>
class CSerialize
{
public:
template <typename T>
friend CSerialize& operator << (CSerialize& lhs, const T& rhs);

private:
// Removed the deque.
//Policy based mutex that is part of the ThreadingPolicy template
mutable typename ThreadingPolicy::Mutex m_Mutex;
};

// namespace Math
// {
template <typename Storage = ptr_t, typename ThreadModel = SingleThreadModel>
class CBigVariableUnsignedInteger
{
public:
template <typename AnyThreadingPolicySerial>
friend CSerialize<AnyThreadingPolicySerial>& operator << (CSerialize<AnyThreadingPolicySerial>& lhs, const CBigVariableUnsignedInteger& rhs)
{
lhs.m_Mutex.lock();
lhs.m_Mutex.unlock();

return lhs;
}
};
// }

int main()
{
CSerialize<> cser;
CBigVariableUnsignedInteger<> bigint;
// Math::CBigVariableUnsignedInteger<> bigint;

cser << bigint;

return 0;
}





Remove the comments on the few lines, and you're in trouble. I'm too tired to look at where the scoping breaks, but hope that helps.

Share this post


Link to post
Share on other sites
Penance: I think you missed the point. The friend template declration should allow anyone who overloads the "operator <<" to have acces to the deque and the mutex.

cbl:
OK. I had seriously stripped down the code for the example. There is actually 2 layers of namespaces above each on of those classes in the real version of the code. I was actually kind of afraid that it might be namespace related.

I am still debating wther or not I should even pursue this. I do have working overloads for all the builtin types. I'm kind of thinking of creating a lock and unlock method for the serialze class. The mutexes I use by default are recursive, so they wont deadlock if lock is called twice, and should be more efficiently. This would allow lock and unlock to still be called from an overloaded "operator <<", but only require them to use lock and unlock and the builtin operators to store data. The whole point being to try and save a few lock and unlocks from being called (if a function didn't lock it before, each operator << call would lock and unlock, but with the recursive mutexes, would just increment a counter.) Kind of locking for the most efficient way of handling it in a multithreading situation. The Single threaded version looks remarkablly like your example. A good compiler should just optimize the calls away.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!