Yanıtlar:
Ileri typedef yapabilirsiniz. Ama yapmak
typedef A B;
ilk önce beyan etmelisiniz A
:
class A;
typedef A B;
typedef
bir ileri bildirimi kullanarak karmaşık çok düzeyli bir şablon türünü bu şekilde adlandırırsanız, oldukça karmaşık ve zordur. Varsayılan şablon argümanlarında gizlenmiş uygulama ayrıntılarına dalmayı gerektirebileceğinden bahsetmiyorum bile. Ve son çözüm, orijinal tipte değişmeye çok eğilimli uzun ve okunamayan bir koddur (özellikle türler çeşitli ad alanlarından geldiğinde).
Benim gibi olanlar için, ileriye bakmak isteyen tip C kullanılarak tanımlanmış bir C tarzı yapı ilan etmek, bazı c ++ kodunda, ben aşağıdaki gibi bir çözüm buldum ...
// 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 bir typedef bildirmek" için fwd bir sınıf ya da bir yapı bildirmeniz gerekir ve daha sonra bildirilen tip yazabilirsiniz. Birden fazla özdeş tip tanımlayıcısı derleyici tarafından kabul edilebilir.
uzun biçim:
class MyClass;
typedef MyClass myclass_t;
kısa form:
typedef class MyClass myclass_t;
C ++ 'da (düz C değil), her iki tanım da tamamen aynı olduğu sürece, bir türü iki kez yazmak tamamen yasaldır :
// foo.h
struct A{};
typedef A *PA;
// bar.h
struct A; // forward declare A
typedef A *PA;
void func(PA x);
// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
A
alanları bu şekilde nasıl tanımlıyorsunuz A
?
Çünkü bir tür beyan etmek için boyutunun bilinmesi gerekir. İşaretçiyi türüne iletebilir veya türe bir işaretçi yazabilirsiniz.
Eğer gerçekten istiyorsanız, pimpl deyimini kullanarak içerilen şeyleri aşağıda tutabilirsiniz. Ancak bir işaretçi yerine bir tür kullanmak istiyorsanız, derleyici boyutunu bilmelidir.
Düzenleme: j_random_hacker boyutu ihtiyaçlarını bilmek gerekir temelde ki bu cevaba önemli bir nitelik katar kullanmak türü, özellikle de bir ileri beyanı yapılabilir sadece tip bilmek gerekiyorsa var , işaretçileri veya referanslar oluşturmak için yazın. OP kod göstermedi, ancak derlemek olmaz şikayet beri, ben OP (sadece doğru) tip sadece kullanmaya değil, tipini kullanmaya çalıştığını varsaydım .
İleri bildirimleri kullanarak yerine tam bir #include
s Eğer sadece zaman mümkündür değil (bu dosyanın kapsamı) türü kendisi ama buna bir işaretçi veya referans kullanarak müstakbel.
Türün kendisini kullanmak için, derleyici boyutunu bilmelidir - bu nedenle tam beyanı görülmelidir - bu nedenle bir tam #include
gereklidir.
Bununla birlikte, bir işaretçi veya referansın boyutu derleyicinin boyutuna bakılmaksızın derleyici tarafından bilinir, bu nedenle ileri bir bildirim yeterlidir - bir tür tanımlayıcı adı bildirir.
İlginç bir şekilde, işaretçi veya referans class
veya struct
türler kullanılırken, derleyici eksik türleri işleyebilir ve ayrıca pointee türlerini de bildirmeniz gerekir:
// header.h
// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;
typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;
// Using the name without the class/struct specifier requires fwd. decl. the type itself.
class C; // fwd. decl. type
typedef C* CPtr; // no class/struct specifier
typedef C& CRef; // no class/struct specifier
struct D; // fwd. decl. type
typedef D* DPtr; // no class/struct specifier
typedef D& DRef; // no class/struct specifier
Aynı sorunu vardı, farklı dosyalarda birden fazla typedefs ile uğraşmak istemiyordu, bu yüzden miras ile çözdüm:
oldu:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
yaptı:
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
Bir cazibe gibi çalıştı. Tabii ki, herhangi bir referansı değiştirmek zorunda kaldım.
BurstBoss::ParticleSystem
basitçe
ParticleSystem
Ben değiştirilir typedef
( using
miras ve yapıcı miras birlikte olmak özgü) (?).
orijinal
using CallStack = std::array<StackFrame, MAX_CALLSTACK_DEPTH>;
Değiştirilen
struct CallStack // Not a typedef to allow forward declaration.
: public std::array<StackFrame, MAX_CALLSTACK_DEPTH>
{
typedef std::array<StackFrame, MAX_CALLSTACK_DEPTH> Base;
using Base::Base;
};
Bu şekilde beyanı şu şekilde iletebildim CallStack
:
class CallStack;
Bill Kotsias'ın belirttiği gibi, noktanızın typedef ayrıntılarını gizli tutmanın ve ileriye beyan etmenin tek makul yolu kalıtımdır. Gerçi C ++ 11 ile biraz daha güzel yapabilirsiniz. Bunu düşün:
// 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;
};
@BillKotsias gibi, kalıtım kullandım ve benim için çalıştı.
Bu karışıklığı değiştirdim.
#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;
bu bildirime (* .h)
class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;
ve uygulama (* .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
>>
{
};