-1

我想我需要一个普通类中的模板友元函数。该函数将在共享内存中进行一些复杂的分配,并在硬件和操作系统中进行一些其他操作。但是我已经排除了所有这些,以表明问题与 -template- 和/或 -friend- 方面有关,而不是更邪恶的东西。主要部分是我需要类的实例及其成员数据都分配有一个分配器,我可以将其作为通用参数传递。

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));
);

我认为这应该是正确的解决方案。只有 alloc_Foo 应该调用构造函数,只有工厂方法应该调用 alloc_Foo。Foo 的实例及其单独分配的内部部分是在它们应该在的共享内存中创建的,所有复杂的分配内容都隐藏在 alloc_Foo 朋友模板中。这部分我可以正常工作。我什至不介意在同一个文件中实现 alloc_Foo,因为它简短而简单。但是调用 alloc_Foo 的工厂又大又复杂,并且会弄乱一个包含数十个包含和数百行代码的原本干净而简单的类。

我试图在最后包含实现,这样我就可以将每个工厂放在一个单独的文件中。

#include "factory_A.tpp"
#include "factory_B.tpp"
// etc.

然后在 .tpp 文件中我放置了实际代码,但我似乎无法包含任何内容,比如 bar.h。#include 规则似乎分崩离析。恐怕与我的模板分配器朋友有关。我肯定不想失去它,因为它解决了我的许多其他问题。

../blah/blah/factory_A.tpp:10:9: error: 'Bar' was not declared in this scope
make: *** [blah/blah/main.o] Error 1

通常我不会对范围交易如此执着,但这对我来说是一个不寻常的组合。也许我在考虑整个交易。我认为 alloc_Foo 必须是一个朋友,所以它可以看到我隐藏的构造函数。我认为它也应该是私有的,只有工厂才能使用它。我认为分配器和工厂实际上都不是函数的一部分。他们没有或不需要“这个”。也许它们应该是静态的。我认为它必须是一个模板,因为我需要在许多内部部分和每个实例的实际对象本身上使用一个特殊的分配器。它应该是静态的。

有人可以帮忙吗?

谢谢。

4

1 回答 1

0

我确信这与模板或朋友无关。预处理器对模板或朋友一无所知,它只是打开文件并将其内容插入其他文件,模板和朋友不可能“使包含规则分崩离析”。你在做什么应该没问题。

检查包含警卫bar.h,它们是否与其他文件相同?

您是否#include "factory_A.tpp"在某些命名空间范围打开时?尝试在文件底部的额外包含之前关闭命名空间。

或者Bar在某个命名空间中,你应该说x::Bar

你是不是捡错了bar.h?尝试将头文件重命名为其他名称,即不会调用其他头文件的独特名称,然后将其更改#include为。

如果这些都不起作用,请将代码简化为重现问题的最小完整示例。目前,您没有显示足够的代码来查看真正的问题在哪里,但几乎可以肯定这不是您所建议的,而是您未显示的代码中的其他地方。

于 2013-01-08T02:00:45.333 回答