15

クラス内で typedef を前方宣言するための最良の解決策は何ですか。これが私が解決する必要があるものの例です:

class A;
class B;

class A
{
    typedef boost::shared_ptr<A> Ptr;

    B::Ptr foo();
};

class B
{
    typedef boost::shared_ptr<B> Ptr;

    A::Ptr bar();
};

私はちょうど次のことができると思います:

boost::shared_ptr<B> foo();

しかし、よりエレガントなソリューションはありますか?

4

5 に答える 5

13

typedef残念ながら、前方宣言などというものはありません。ただし、後半のテンプレートのインスタンス化を使用するトリックがあります。

template <typename T> class BImpl;

template <typename T>
class AImpl
{
public:
    typedef boost::shared_ptr<AImpl> Ptr;
    typename BImpl<T>::Ptr foo();
};

template <typename T>
class BImpl
{
public:
    typedef boost::shared_ptr<BImpl> Ptr;
    typename AImpl<T>::Ptr bar();
};

typedef AImpl<void> A;
typedef BImpl<void> B;

これは、うまくいけば、あなたが目指していることを達成するはずです。

于 2013-06-06T15:57:43.107 に答える
4

2 つの明確な困難に直面しています: 1. typedef の前方宣言はありません 2. ネストされた型の前方宣言は不可能です

2 番目の方法はありません。型のネストを解除する必要があります。

私がときどき使用する最初の回避策の 1 つは、派生型を作成することです。それは、はい、前方宣言できます。

言う:

struct Ptr : shared_ptr<A> {};

これは新しいタイプですが、シノニムとほぼ同じです。もちろん、問題はコンストラクターですが、C++11 ではそれが改善されています。

もちろん、この答えは一般的なものです。あなたの特定のケースでは、クラスの外で Ptrs を定義する必要があり、まったく問題はないと思います。

struct A;
struct B;
typedef shared_ptr<A> APtr;
typedef shared_ptr<B> BPtr;

そしてクラス。

于 2013-06-06T16:13:04.307 に答える
2

それはいけません。

ただし、クラスの Ptr 定義を切り離すことができます。

class A;
class B;

template <typename T>
struct Traits {
    typedef std::shared_ptr<A>  Ptr; 
};

class A
{
    Traits<B>::Ptr foo();
};

class B
{
    Traits<A>::Ptr bar();
};

A と B が同じタイプを共有していない場合は、常にすべてのタイプの特性を特殊化できます。

于 2013-06-06T16:12:14.953 に答える
2

他の人が指摘したように、typedef を前方宣言することはできません。これは、typedef が実際にはそれ自体の「型」ではなく、他の型のエイリアスであるためです (したがって、「using Int = int;」などの C++11 の「型エイリアス」と同等の概念)。つまり、たとえば、typedef はマングルされた名前などの ABI 要素には表示されないため、コンパイラは、すべての ABI 要件 (型名をマングルする方法を含む) を満たすために、基礎となる型を十分に認識している必要があります。

于 2013-06-06T16:13:34.397 に答える