2

私は次のクラスを持っています:

#include <set>
#include <stack>
#include <queue>
#include <string>

template <typename T>
class MySet
{
    public:
        const std::stack<T> data() const
        {
            std::stack<T> other_cont ( typename std::stack<T>::container_type ( cont.begin(), cont.end() ) );
            return other_cont;
        }

    private:
        std::set<T> cont;
};

そして、次のコード:

MySet<std::string> a;
MySet<int> b;

const std::stack<std::string> s = a.data();
const std::queue<int> q = b.data();

1 つのテンプレート化されたメンバー関数を使用して、アダプターの型を初期化したいと考えています。これまでのところ、またはのいずれかでのみ機能しますstackqueueテンプレートを使用して一般化する方法がわかりません。

これは私が試したことです:

template <template <typename> typename M>
const M<T> data() const
{
    M<T> other_cont ( typename M<T>::container_type ( cont.begin(), cont.end() ) );
    return other_cont;
}

コンパイラは、テンプレート パラメータを推測できないと言っていますM

4

2 に答える 2

3

簡単な方法は、変換演算子を使用することです。

#include <set>
#include <stack>
#include <queue>
#include <string>

template <typename T>
class MySet
{
    public:
        template <typename O, typename = typename O::container_type>
        operator O() const
        {
            return O(typename O::container_type(cont.begin(), cont.end()));
        }

    private:
        std::set<T> cont;
};

ただし、このアプローチを使用すると、表記が異なります。data()使用されているメンバーはありません。

int main()
{
    MySet<std::string> s;
    std::stack<std::string> st = s;
    std::queue<std::string> qu = s;
} 

メンバーを使用しdata()て結果から異なる型を取得する場合は、アクセス時に適切に変換されるプロキシを返す必要があります。

#include <set>
#include <stack>
#include <queue>
#include <string>

template <typename T>
class MySet
{
    public:
        class Proxy {
            std::set<T> const* set;
        public:
            Proxy(std::set<T> const* s): set(s) {}
            template <typename O, typename = typename O::container_type>
            operator O() const
            {
                return O(typename O::container_type(set->begin(), set->end()));
            }
        };

        Proxy data() const { return Proxy{&this->cont}; }
    private:
        std::set<T> cont;
};

int main()
{
    MySet<std::string> s;
    std::stack<std::string> st = s.data();
    std::queue<std::string> qu = s.data();
} 
于 2016-12-19T18:17:46.323 に答える
3

呼び出しコードを検討してください。

a.data()

data()戻り値の型を推測するものは何もありません。次のように、明示的に正確にする必要があります。

a.data<std::stack>()

しかし、あなたのコメントから、使用法コードを編集することはできません。あなたができることは、テンプレート型変換演算子を使用することです:

template <typename M>
operator M() const
{
    M other_cont ( typename M::container_type ( cont.begin(), cont.end() ) );
    return other_cont;
}

コードを未編集のままにしておくには、dataメソッドは次のオブジェクトを返す必要があります。

const MySet<T> data() const
{
    return *this;
}
于 2016-12-19T18:19:09.453 に答える