如何创建可以使用不同类型参数处理std::set的模板类 我需要在C++中编写一个模板来实现一个集合的抽象版本。我找不到解决编译错误的方法(更糟的是,我真的不知道该怎么办)
这是我需要编译和运行的主程序的简化版本——也就是说,我不能更改以下内容:如何创建可以使用不同类型参数处理std::set的模板类 我需要在C++中编写一个模板来实现一个集合的抽象版本。我找不到解决编译错误的方法(更糟的是,我真的不知道该怎么办),c++,class,templates,set,C++,Class,Templates,Set,这是我需要编译和运行的主程序的简化版本——也就是说,我不能更改以下内容: #include <algorithm> #include <iostream> #include <iterator> #include <numeric> #include <set> #include <string> #include "testset.h" using namespace std; struct string_size_l
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <set>
#include <string>
#include "testset.h"
using namespace std;
struct string_size_less
{
bool operator()( const std::string& a,
const std::string& b )
{
return a.size() < b.size();
}
};
int main()
{
std::set<std::string> msgs;
msgs.insert("One");
msgs.insert("Two");
msgs.insert("Three");
set_ops<std::string> ops(msgs);
ops.list();
std::set<std::string, string_size_less> x;
x.insert("Hello");
x.insert("Ciao");
std::set<std::string, std::greater<std::string> > a;
a.insert(":-o");
set_ops<std::string> m(x);
m.list();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括“testset.h”
使用名称空间std;
结构字符串大小小于
{
布尔运算符()(常量std::string&a,
const std::string(字符串和b)
{
返回a.size()
我需要编写“set_ops”类(在testset.h中)。我剥离了所有不相关的部分(否则会起作用):
#pragma一次
#包括
#包括
使用名称空间std;
模板类集合
{
私人:
std::集合元素;
公众:
集合操作(标准::集合初始集合)
{
元素=初始集;
}
无效列表()常量;
};
模板无效集_ops::list()常量
{
for(typename set::iterator i=elements.begin();i!=elements.end();++i){
这可以通过多态性和模板构造函数来实现
#include <utility>
#include <memory>
#include <iostream>
template <typename T>
class set_ops
{
private:
// Interface type.
class set_ops_iface
{
public:
virtual ~set_ops_iface();
virtual void list() const = 0;
};
// Concrete implementation for a U.
template <typename U>
class set_ops_impl : public set_ops_iface
{
private:
U value;
public:
explicit set_ops_impl(U);
virtual void list() const override;
};
private:
// Smart pointer to interface type.
std::unique_ptr<set_ops_iface> impl;
public:
// Template constructor that can take any kind of container (not just sets)
template <typename U>
set_ops(U);
void list() const;
};
// Template constructor creates a set_ops_impl<U> owned by the interface smart pointer.
template <typename T>
template <typename U>
set_ops<T>::set_ops(U initial) :
impl{std::make_unique<set_ops_impl<U>>(std::move(initial))} { }
template <typename T>
set_ops<T>::set_ops_iface::~set_ops_iface() { }
template <typename T>
template <typename U>
set_ops<T>::set_ops_impl<U>::set_ops_impl(U initial) :
value{std::move(initial)} { }
// real list() implementation is in set_ops_impl<U>
template <typename T>
template <typename U>
void set_ops<T>::set_ops_impl<U>::list() const {
for (auto const & i : value) {
std::cout << '\t' << i << '\n';
}
}
// set_ops::list proxies to the polymorphic implementation.
template <typename T>
void set_ops<T>::list() const {
impl->list();
}
#包括
#包括
#包括
模板
类集合运算
{
私人:
//接口类型。
类集_ops _iface
{
公众:
虚拟~set_ops_iface();
虚空列表()常量=0;
};
//具体执行一项联合国决议。
模板
类集合操作简易:公共集合操作简易
{
私人:
U值;
公众:
显式集合运算显式(U);
虚空列表()常量覆盖;
};
私人:
//指向接口类型的智能指针。
std::唯一的\u ptr impl;
公众:
//可以接受任何类型容器(而不仅仅是集合)的模板构造函数
模板
设置操作(U);
无效列表()常量;
};
//模板构造函数创建由接口智能指针拥有的集合操作impl。
模板
模板
设置操作::设置操作(U首字母):
impl{std::make_unique(std::move(initial))}{
模板
set_ops::set_ops_iface::~set_ops_iface(){}
模板
模板
集合运算::集合运算执行::集合运算执行(U首字母):
值{std::move(初始)}{}
//real list()实现在set_ops_impl中
模板
模板
void set_ops::set_ops_impl::list()常量{
用于(自动常量和i:值){
这可以通过多态性和模板构造函数来实现
#include <utility>
#include <memory>
#include <iostream>
template <typename T>
class set_ops
{
private:
// Interface type.
class set_ops_iface
{
public:
virtual ~set_ops_iface();
virtual void list() const = 0;
};
// Concrete implementation for a U.
template <typename U>
class set_ops_impl : public set_ops_iface
{
private:
U value;
public:
explicit set_ops_impl(U);
virtual void list() const override;
};
private:
// Smart pointer to interface type.
std::unique_ptr<set_ops_iface> impl;
public:
// Template constructor that can take any kind of container (not just sets)
template <typename U>
set_ops(U);
void list() const;
};
// Template constructor creates a set_ops_impl<U> owned by the interface smart pointer.
template <typename T>
template <typename U>
set_ops<T>::set_ops(U initial) :
impl{std::make_unique<set_ops_impl<U>>(std::move(initial))} { }
template <typename T>
set_ops<T>::set_ops_iface::~set_ops_iface() { }
template <typename T>
template <typename U>
set_ops<T>::set_ops_impl<U>::set_ops_impl(U initial) :
value{std::move(initial)} { }
// real list() implementation is in set_ops_impl<U>
template <typename T>
template <typename U>
void set_ops<T>::set_ops_impl<U>::list() const {
for (auto const & i : value) {
std::cout << '\t' << i << '\n';
}
}
// set_ops::list proxies to the polymorphic implementation.
template <typename T>
void set_ops<T>::list() const {
impl->list();
}
#包括
#包括
#包括
模板
类集合运算
{
私人:
//接口类型。
类集_ops _iface
{
公众:
虚拟~set_ops_iface();
虚空列表()常量=0;
};
//具体执行一项联合国决议。
模板
类集合操作简易:公共集合操作简易
{
私人:
U值;
公众:
显式集合运算显式(U);
虚空列表()常量覆盖;
};
私人:
//指向接口类型的智能指针。
std::唯一的\u ptr impl;
公众:
//可以接受任何类型容器(而不仅仅是集合)的模板构造函数
模板
设置操作(U);
无效列表()常量;
};
//模板构造函数创建由接口智能指针拥有的集合操作impl。
模板
模板
设置操作::设置操作(U首字母):
impl{std::make_unique(std::move(initial))}{
模板
set_ops::set_ops_iface::~set_ops_iface(){}
模板
模板
集合运算::集合运算执行::集合运算执行(U首字母):
值{std::move(初始)}{}
//real list()实现在set_ops_impl中
模板
模板
void set_ops::set_ops_impl::list()常量{
用于(自动常量和i:值){
std::cout另一个答案之所以有效,是因为std::function
使用了一种称为“类型擦除”的技术。如果您不想保留多个std::functions
,您可以自己实现类型擦除
template<typename T>
struct set_ops_erased {
virtual ~set_ops_erased() = default;
virtual void list() = 0;
};
template<typename T, typename Comp>
struct set_ops_impl : set_ops_erased<T> {
std::set<T, Comp> s;
set_ops_impl(std::set<T, Comp> s) : s(std::move(s)) { }
void list() override {
for(auto &x : s) std::cout << "\t" << x << "\n"; // endl is normally not necessary
}
};
template<typename T>
class set_ops {
std::unique_ptr<set_ops_erased<T>> ops;
public:
template<typename Comp>
set_ops(std::set<T, Comp> s)
: ops(std::make_unique<set_ops_impl<T, Comp>>(std::move(s)))
{ }
void list() { ops->list(); }
};
模板
结构集\u操作\u已删除{
virtual~set_ops_erased()=默认值;
虚空列表()=0;
};
模板
结构集合操作执行:集合操作已擦除{
std::集s;
set_ops_impl(std::set s):s(std::move(s)){
无效列表()覆盖{
对于(auto&x:s)std::cout另一个答案有效,因为std::function
使用了一种称为“类型擦除”的技术。如果您不想保留多个std::functions
,您可以自己实现类型擦除
template<typename T>
struct set_ops_erased {
virtual ~set_ops_erased() = default;
virtual void list() = 0;
};
template<typename T, typename Comp>
struct set_ops_impl : set_ops_erased<T> {
std::set<T, Comp> s;
set_ops_impl(std::set<T, Comp> s) : s(std::move(s)) { }
void list() override {
for(auto &x : s) std::cout << "\t" << x << "\n"; // endl is normally not necessary
}
};
template<typename T>
class set_ops {
std::unique_ptr<set_ops_erased<T>> ops;
public:
template<typename Comp>
set_ops(std::set<T, Comp> s)
: ops(std::make_unique<set_ops_impl<T, Comp>>(std::move(s)))
{ }
void list() { ops->list(); }
};
模板
结构集\u操作\u已删除{
virtual~set_ops_erased()=默认值;
虚空列表()=0;
};
模板
结构集合操作执行:集合操作已擦除{
std::集s;
set_ops_impl(std::set s):s(std::move(s)){
无效列表()覆盖{
对于(auto&x:s)std::cout,不更改主文件,但忘记给定集合的初始顺序(因为您没有指定预期输出),您可以执行以下操作:
template <class T> class set_ops
{
private:
std::set<T> elements;
public:
template <typename Container>
set_ops(Container& c) : elements(c.begin(), c.end()) {}
void list() const {
for (const auto& e : elements) {
std::cout << "\t" << e << std::endl;
}
}
};
模板类集合
{
私人:
std::集合元素;
公众:
模板
集合操作(容器&c):元素(c.begin(),c.end()){}
无效列表()常量{
用于(常量自动和e:元素){
std::cout不更改主文件,但忘记给定集合的初始顺序(因为您没有指定预期输出),您可以执行以下操作:
template <class T> class set_ops
{
private:
std::set<T> elements;
public:
template <typename Container>
set_ops(Container& c) : elements(c.begin(), c.end()) {}
void list() const {
for (const auto& e : elements) {
std::cout << "\t" << e << std::endl;
}
}
};
模板类集合
{
私人:
std::集合元素;
公众:
模板
集合操作(容器&c):元素(c.begin(),c.end()){}
无效列表()常量{
用于(常量自动和e:元素){
std::cout AFAIK如果不更改main
@NathanOliver,则无法执行此操作。滥用多态性确实可以。是否指定了输出?否则您可以复制内容并更改顺序。AFAIK如果不更改main
@NathanOliver,则无法执行此操作确实可以滥用多态性
template <class T> class set_ops
{
private:
std::set<T> elements;
public:
template <typename Container>
set_ops(Container& c) : elements(c.begin(), c.end()) {}
void list() const {
for (const auto& e : elements) {
std::cout << "\t" << e << std::endl;
}
}
};