I think I need a template friend function in a normal class. This function will be doing some complicated allocation in shared memory and some other poking around in the hardware and OS. But I have excluded all of that to show the problem is related to the -template- and/or -friend- aspects and not something more sinsiter. The main part is that I need the instance of the class and its member data all be allocated with an allocator that I can pass as a generic parameter.
class Foo {
public:
const long * const larry;
const long * const curly;
const long * const moe;
private:
Foo() : larry(0), curly(0), moe(0) {}; // not used
Foo(long * _larry, long * _curly, long * _moe) :
: larry(_larry), curly(_curly), moe(_moe)
{
// some unrelated memory management and OS stuff happens here
}
template<class Alloc> friend const Foo * alloc_Foo(long count);
public: // factories
template<class Alloc> const Foo * factory_A(long);
// template<class Alloc> const Foo * factory_B(long);
// ...
// template<class Alloc> const Foo * factory_G(long);
};
template<class Alloc> const Foo * alloc_Foo(long count)
{
typename Alloc::template rebind<long>::other a_long;
// allocate internal parts in shared memory
const long * const larry = a_long.allocate(count+2);
const long * const curly = a_long.allocate(count+44);
const long * const moe = a_long.allocate(count*3);
Alloc alloc;
const Foo * const p_foo = alloc.allocate(1);
alloc.construct(p_foo, Foo(larry, curly, moe));
);
I think this should be the right solution. Only alloc_Foo should call the constructor and only the factory methods should call alloc_Foo. Instance of Foo and its separately allocated internal parts are created in shared memory where they are supposed to be and all of complicated allocation stuff is hidden in the alloc_Foo friend template. This part I can get to work fine. I don't even mind having the implementation for alloc_Foo in the same file because it is short and simple. But the factories that call alloc_Foo are large and complex and would clutter up an otherwise clean and simple class with tens of includes and many hundreds of lines of code.
I tried to include the implementations at the end so I could have each factory in a separate file.
#include "factory_A.tpp"
#include "factory_B.tpp"
// etc.
Then in the .tpp files I put the actual code but I cannot seem to include anything, say bar.h, there. The #include rules seem to fall apart. I'm afraid that it has something to do with my template allocator friend. I would sure hate to lose that since it solves so many of my other problems.
../blah/blah/factory_A.tpp:10:9: error: 'Bar' was not declared in this scope
make: *** [blah/blah/main.o] Error 1
Normally I wouldn't be so hung up on a scope deal but this is an unusal combination for me. Maybe I'm overthinking the whole deal. I reason that alloc_Foo must be a friend so it can see the constructors I am hiding. I reason that it should also be private and that only the factories should be able to use it. I reason that both the allocator and factories are not actually part of the function. They don't have or need 'this'. Maybe they should be static. I reason that it must be a template because I need to use a special allocator on many internal parts and the actual object itself for each instance. Should it be static.
Can anybody help?
Thanks.