Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何用模板概括容器适配器?_C++_Templates_Stack_Queue_Conversion Operator - Fatal编程技术网

C++ 如何用模板概括容器适配器?

C++ 如何用模板概括容器适配器?,c++,templates,stack,queue,conversion-operator,C++,Templates,Stack,Queue,Conversion Operator,我有以下课程: #include <set> #include <stack> #include <queue> #include <string> template <typename T> class MySet { public: const std::stack<T> data() const { std::stack<T> other_c

我有以下课程:

#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;
};

编译器说它无法推断模板参数
M

简单的方法是使用转换运算符:

#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;
};
template <typename M>
operator M() const
{
    M other_cont ( typename M::container_type ( cont.begin(), cont.end() ) );
    return other_cont;
}
如果要使用
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();
} 
#包括
#包括
#包括
#包括
模板
类MySet
{
公众:
类代理{
std::set const*set;
公众:
代理(std::set const*s):集{}
模板
运算符O()常量
{
返回O(typename O::container_type(set->begin(),set->end());
}
};
代理数据()常量{return Proxy{&this->cont};}
私人:
std::set cont;
};
int main()
{
迈塞特s;
std::stack st=s.data();
std::queue qu=s.data();
} 

考虑一下您的呼叫代码:

a.data()
这里没有任何内容可供
data()
推断其返回类型。您必须明确地对其进行精确,例如:

a.data<std::stack>()

我认为在你的情况下,编译器永远无法推断出参数。Try const
std::queue q=b.data()
甚至
std::queue q=b.data()抱歉,我没有提到这是过去几年考试中的一些材料的一部分,我无法触及第二块代码。我只是认为我应该用模板解决这个问题,因为这两个适配器的代码似乎是相同的。将其包装在代理类中而不是在MySet中定义转换运算符是否有好处?(就像在@wasthisfulsive-s答案中)对于
typename=typename O::container\u type
,如果我只使用
模板
,我会丢失任何东西吗?@Jani:基本上,错误消息是不同的。如果目标类型没有嵌套的
容器类型,则使用我的SFINAE方法会说没有合适的转换运算符。如果没有它,就会出现实现错误的错误。在SFINAE上下文中,我的实现不会声称它是可转换的。是否使用代理取决于是否要强制提及
data()
a.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;
}
const MySet<T> data() const
{
    return *this;
}