如何使用模板泛化容器适配器?
How to generalize container adaptors with templates?
我得到了以下 class:
#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();
我想使用一个模板化成员函数来初始化任何适配器类型。
到目前为止,它只适用于 stack
或 queue
,我不知道如何使用模板来概括它。
这是我试过的:
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
。
简单的方法是使用转换运算符:
#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()
成员并从结果中获得不同的类型,您将需要 return 一个在访问时适当转换的代理:
#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();
}
考虑您的调用代码:
a.data()
data()
这里没有任何东西可以推断其 return 类型。你必须明确地精确它,比如:
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
方法应该 return 这个对象:
const MySet<T> data() const
{
return *this;
}
我得到了以下 class:
#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();
我想使用一个模板化成员函数来初始化任何适配器类型。
到目前为止,它只适用于 stack
或 queue
,我不知道如何使用模板来概括它。
这是我试过的:
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
。
简单的方法是使用转换运算符:
#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()
成员并从结果中获得不同的类型,您将需要 return 一个在访问时适当转换的代理:
#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();
}
考虑您的调用代码:
a.data()
data()
这里没有任何东西可以推断其 return 类型。你必须明确地精确它,比如:
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
方法应该 return 这个对象:
const MySet<T> data() const
{
return *this;
}