2
#include "MassivePOD.h"
#include "DependantClass.h" // Constructor: `DependantClass(MassivePOD&)`

class ExplicitSolution
{
public:
    ExplicitSolution() : m_pod{...}, m_dep{m_pod} { };
private:
    MassivePOD  m_pod;
    DependantClass  m_dep;
};

template<typename... T>
class TemplatedSolution
{
public:
    template<typename... TupArgs> TemplatedSolution(TupArgs...);
private:
    // Can assume in-order construction works
    std::tuple<T...>  m_tuple;
};


int main()
{
    ExplicitSolution a{}; // Easy!
    TemplatedSolution<MassivePOD, DependantClass> b{
        std::forward_as_tuple(...) // Forwarded to MassivePOD constructor
      , std::forward_as_tuple(???) // Forwarded to DependantClass constructor
        }; // Hard?
}

この例が私の問題を示していることを願っています。std::tuple全体std::tupleが構築される前に、以前に構築されたメンバーを参照したいと思います。これに対するエレガントな解決策はありますか?ハッカーを使えばそれが可能であることはわかっていvoid *ますが、その暗い孤独な道を進む前に助けを求めたいと思います.

アイデア1

関数を作成しようとしましたget_refが、まだ作成されていないオブジェクトのメンバー関数にアクセスできないという同じ問題が発生します。とにかく、これは私の試みの1つです。

#include <tuple>
#include <utility>

class Foo // simplified base-case
{
public:
    constexpr Foo(int x, char y, int& z) : m_tup{x, y, z*5.0} { };

    constexpr int& get_int() { return std::get<0>(m_tup); };
    constexpr char& get_char() { return std::get<1>(m_tup); };
    constexpr double& get_double() { return std::get<2>(m_tup); };

private:
    std::tuple<int, char, double>  m_tup;
};

int main()
{
    auto super = Foo(5, 'a', ::get_int()); // ???
}

デモ

アイデア2

次に、 の各要素がどこにあるかへのポインター/参照を含む静的オブジェクトを使用std::functionして、 で行うことのようなことができるのではないかと考えました。これは試してみる価値があると思いますが、実際に実装する方法がわかりません...std::place_holdersstd::tuple

4

2 に答える 2

1

別の提案: タプル クラスは、メンバーのコンストラクターのパラメーターを取得するのではなく、構築中のインスタンスを受け取り、メンバーを返す関数を取得します。これらの関数は、ゲッターを介して以前に構築されたメンバーを参照できます。必要なのは、前のメンバーのゲッターが機能し、後のメンバーが構築されている間に呼び出された場合に未定義の動作を呼び出さないことを確認することだけです。

原理を示すために 2 つの要素をハードコーディングした例を次に示します。n要素で動作するようにするのはあなたに任せます。基本的に、ここでタプルを再実装することになることに注意してください。既存の でこれを実行できるかどうかはわかりませんstd::tuple

template<typename A, typename B>
class TemplatedSolution
{
public:
    template<typename AF, typename BF> TemplatedSolution(AF af, BF bf)
        : a(af(*this))
        , b(bf(*this))
    {
    }

    A& get_first() {
        return a;
    }

    B& get_second() {
        return b;
    }

private:
    A a;
    B b;
};

使用法:

typedef TemplatedSolution<MassivePOD, DependantClass> ClassT;

ClassT b{
    [](ClassT& res) { return MassivePOD(); },
    [](ClassT& res) { return DependantClass(res.get_first()); },
};

戻り値の最適化により、MassivePODs はインスタンス内で正しく構築されTemplatedSolutionます。

コピーがないことを示す完全に機能する例は、こちらで入手できます。

于 2015-10-05T15:35:45.300 に答える