C++ 使用指令进行前向声明

问题描述 投票:0回答:3

我有一个标头,它通过使用公开模板化类和 typedef,例如:

namespace fancy {

  struct Bar {
     ...
  }

  template<typename T>
  class Foo {
     ...
  }

  using FooBar = Foo<Bar>;
}

我想转发声明

FooBar
以在另一个标头的
shared_ptr
中使用它。我试过了

namespace fancy {
  using FooBar;
}

就像一个类或结构,但没有运气。这可能吗?如果可以,如何实现?

c++ c++11 using forward-declaration
3个回答
30
投票

您无法在未定义别名的情况下声明

using
别名。但是,您可以声明类模板而不定义它,并使用重复的
using
别名:

namespace fancy {
    template <typename> class Foo;
    class Bar;
    using FooBar = Foo<Bar>;
}

6
投票

使用前向声明的另一种方法是将

using
替换为类继承:

// using FooBar = Foo<Bar>;
class FooBar : public Foo<Bar> {};

当然,现在

FooBar
Foo<Bar>
不是一回事。例如,您需要通过
using Foo<Bar>::Foo
继承可能存在的构造函数,但作为一个好处,您可以像往常一样使用简单的前向声明。只是:

namespace fancy {
    class FooBar;
}

5
投票

如果你的 using 声明太大(很多模板参数,它们又由 using 语句定义),你还可以添加一个虚拟 forward 结构,将 using 类型作为依赖类型:

    namespace fancy {

        struct Bar {
            ...
        }

        template<typename T>
        class Foo {
            ...
        }

        using FooBar = Foo<Bar>;

        // Forward struct
        struct FooBarFwd {
            using type = FooBar;
        }
    }

然后在您要转发的地方声明:

    namespace fancy {
        class FooBarFwd;
    }
    // use your type as
    typename FooBarFwd::type baz(const typename FooBarFwd::type & myFooBar);
    // instead of
    // FooBar baz(const FooBar & myFooBar);

这种方法的一些缺点是

  • 使用
    typename
    消除依赖类型的歧义。
  • 对于您的类型有额外的间接寻址,某些编译器在报告错误时可能会出现问题。
  • 更改为这种方法可能需要对代码进行大量更改(将每次出现的
    FooBar
    更改为
    typename FooBarFw::type

因此,我建议仅当您确定自己在做什么时才应用此技术。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.