为什么编译器不让我向前声明类型定义?

假设这是不可能的,那么保持我的包含树小的最佳实践是什么?


当前回答

像@BillKotsias一样,我使用了继承,而且它对我很有效。

我改变了这个混乱(这需要所有的boost头在我的声明*.h)

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>

typedef boost::accumulators::accumulator_set<float,
 boost::accumulators::features<
  boost::accumulators::tag::median,
  boost::accumulators::tag::mean,
  boost::accumulators::tag::min,
  boost::accumulators::tag::max
 >> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;

在这个声明中(*.h)

class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;

实现(*.cpp)是

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>

class VanillaAccumulator : public
  boost::accumulators::accumulator_set<float,
    boost::accumulators::features<
      boost::accumulators::tag::median,
      boost::accumulators::tag::mean,
      boost::accumulators::tag::min,
      boost::accumulators::tag::max
>>
{
};

其他回答

正如Bill Kotsias所指出的,保持点的typedef细节为私有并向前声明的唯一合理方法是继承。不过,使用c++ 11可以做得更好一些。考虑一下:

// LibraryPublicHeader.h

class Implementation;

class Library
{
...
private:
    Implementation* impl;
};
// LibraryPrivateImplementation.cpp

// This annoyingly does not work:
//
//     typedef std::shared_ptr<Foo> Implementation;

// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
    // C++11 allows us to easily copy all the constructors.
    using shared_ptr::shared_ptr;
};

因为要声明一个类型,就需要知道它的大小。可以前向声明指向该类型的指针,也可以对指向该类型的指针进行类型定义。

如果您真的想这样做,您可以使用pimpl习语来减少包含。但是如果你想使用类型,而不是指针,编译器必须知道它的大小。

Edit: j_random_hacker为这个答案添加了一个重要的限定条件,基本上是需要知道该类型的大小才能使用该类型,但是如果我们只需要知道该类型的存在,就可以进行前向声明,以便创建指向该类型的指针或引用。由于OP没有显示代码,但抱怨它不会编译,我假设(可能是正确的)OP试图使用类型,而不仅仅是引用它。

像@BillKotsias一样,我使用了继承,而且它对我很有效。

我改变了这个混乱(这需要所有的boost头在我的声明*.h)

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>

typedef boost::accumulators::accumulator_set<float,
 boost::accumulators::features<
  boost::accumulators::tag::median,
  boost::accumulators::tag::mean,
  boost::accumulators::tag::min,
  boost::accumulators::tag::max
 >> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;

在这个声明中(*.h)

class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;

实现(*.cpp)是

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>

class VanillaAccumulator : public
  boost::accumulators::accumulator_set<float,
    boost::accumulators::features<
      boost::accumulators::tag::median,
      boost::accumulators::tag::mean,
      boost::accumulators::tag::min,
      boost::accumulators::tag::max
>>
{
};

对于那些像我一样,希望在一些c++代码中前向声明使用typedef定义的c风格结构体的人,我已经找到了一个解决方案,如下所示…

// a.h
 typedef struct _bah {
    int a;
    int b;
 } bah;

// b.h
 struct _bah;
 typedef _bah bah;

 class foo {
   foo(bah * b);
   foo(bah b);
   bah * mBah;
 };

// b.cpp
 #include "b.h"
 #include "a.h"

 foo::foo(bah * b) {
   mBah = b;
 }

 foo::foo(bah b) {
   mBah = &b;
 }

要“fwd声明一个类型定义”,你需要fwd声明一个类或结构,然后你可以typedef声明类型。编译器可以接受多个相同的类型。

长形式:

class MyClass;
typedef MyClass myclass_t;

简式:

typedef class MyClass myclass_t;