应替换现有类型,添加新类型

2024-03-11

我有一个基地std::vector和一个std::initializer_list<Attribute*>,它是由派生类组成的函数的参数Attribute class.

class Attribute {};
class Place : public Attribute {};
class Time : public Attribute {};
class Way: public Attribute {};

Place* place = new Place();
Time* time = new Time();
Way* way = new Way();
Place* place2 = new Place(...);
Time* time2 = new Time(...);

auto baseList = std::vector<Attribute*>({ place, time, way })

void updateBaseList(std::vector<Attribute*>& v, std::initializer_list<Attribute*> l);

What updateBaseList必须做的是,如果元素的类型l等于一baseList,更新该值baseList与其中之一l。如果没有遇到该类型baseList,它必须添加到它。

请注意,正在搜索的类型不是Attribute*,而是派生类。

我的尝试

void updateBaseList(std::vector<Attribute*>& v, std::initializer_list<Attribute*> l) {
    bool found;
    for (auto listIt = l.begin(); listIt != l.end(); ++listIt) {
        found = false;
        for (auto attrIt = baseList.begin(); attrIt != baseList.end(); ++attrIt) {
            if (typeid(**listIt) == typeid(**attrIt)) {
                *attrIt = *listIt;
                found = true;
                break;
            }
        }
        if (!found) {
            baseList.push_back(*listIt);
        }
    }
}

But the typeid(**listIt) and typeid(**attrIt)总是回来Base.

The goal

如果我打电话updateBaseList(baseList, { time2, place2 })基本列表应该是{ place2, time2, way }


您需要使类层次结构具有多态性。执行此操作的一个好方法是添加virtual ~Attribute() { }析构函数:

struct Attribute 
{
    virtual ~Attribute() { }
};

那么你的代码按预期工作 http://melpon.org/wandbox/permlink/FLTo8aQ4RRk5Y6pp:

{
    auto baseList = std::vector<Attribute*>({ place0, time0 });

    updateBaseList(baseList, {place2, time2, way0});
    assert(baseList[0] == place2);
    assert(baseList[1] == time2);
    assert(baseList[2] == way0);
    assert(baseList.size() == 3);

    updateBaseList(baseList, {place0});
    assert(baseList[0] == place0);
    assert(baseList[1] == time2);
    assert(baseList[2] == way0);
    assert(baseList.size() == 3);
}

不相关,但您可以实施baseList使用 C++11 range-for 循环更容易阅读:

void updateBaseList(std::vector<Attribute*>& v, std::initializer_list<Attribute*> l) 
{
    for (auto& litem : l) 
    {
        bool found = false;
        for (auto& attr : baseList) 
        {
            if (typeid(*litem) != typeid(*attr)) continue;

            attr = litem;
            found = true;
            break;
        }

        if (!found) 
        {
            v.push_back(litem);
        }
    }
}

您还可以利用标准算法来避免有状态的found多变的:

void updateBaseList(std::vector<Attribute*>& v, std::initializer_list<Attribute*> l) 
{
    for (auto& litem : l) 
    {
        const auto found = std::find_if(std::begin(v), std::end(v), [&](Attribute* p)
                                       {
                                           return typeid(*litem) == typeid(*p);
                                       });

        if (found == std::end(v)) 
        {
            v.push_back(litem);
        }
        else 
        {
            *found = litem;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应替换现有类型,添加新类型 的相关文章

  • #include 在 ubuntu 中“没有这样的文件”

    当使用 g std c 0x Wall test cc o hello 编译时 输出致命错误 cstdatomic 没有这样的文件或直接 哪里不见了 包含内容应该是 include
  • HttpResponseMessage 的内容为 JSON

    我有一个 ASP NET MVC WEB API 由于多种原因 由于没有授权而重定向 我不能只使用一个简单的对象并在我的控制器方法中返回它 因此我需要 HttpResponseMessage 类来允许我重定向 目前我正在这样做 var re
  • ZedGraph 缩放和调整大小

    当我绘制图形 放大和缩小并重新绘制图形时 图形的位置不会改变 我想要做的是 每当重新绘制数据时 视图都会更改以查看所有图形数据 如果您在重绘之前放大或缩小 这似乎会被禁用 Thanks 设置属性 IsZoomOnMouseCenter对于控
  • 当“”可以分配给std::string时,为什么有“clear”方法?

    一个可以用string clear函数清空字符串 也可以使用空双引号 来执行此操作 有什么不同 当您分配一个空字符串时 编译器必须在数据部分存储一个空的 C 字符串 并创建代码以将指向它的指针传递给赋值运算符 然后 赋值运算符必须从数据部分
  • 将内核链接到 PTX 函数

    我可以使用 PTX 文件中包含的 PTX 函数作为外部设备函数 将其链接到另一个应调用该函数的 cu 文件吗 这是另一个问题CUDA 将内核链接在一起 https stackoverflow com questions 20636800 c
  • NUnit 测试运行顺序

    默认情况下 nunit 测试按字母顺序运行 有谁知道有什么方法可以设置执行顺序吗 是否存在这样的属性 我只是想指出 虽然大多数受访者认为这些是单元测试 但问题并没有具体说明它们是 nUnit 是一个很棒的工具 可用于各种测试情况 我可以看到
  • .NET 中 IEqualityComparer 中 GetHashCode 的作用是什么?

    我试图了解 IEqualityComparer 接口的 GetHashCode 方法的作用 下面的例子取自MSDN using System using System Collections Generic class Example st
  • “volatile void function( ... )” 做了什么?

    我见过从语法角度来看 C 函数中 volatile 关键字有多少种用法 https stackoverflow com questions 7643528 how many usage does volatile keyword have
  • 编译器在函数名称前添加下划线前缀的原因是什么?

    当我看到 C 应用程序的汇编代码时 如下所示 emacs hello c clang S O hello c o hello s cat hello s 函数名称以下划线作为前缀 例如callq printf 为什么这样做以及它有什么优点
  • 最小对的总和

    Given 2N点 in a 2D plane 你必须将它们分组为N pairs使得所有对的点之间的距离的总和是最小可能值 所需的输出只是总和 换句话说 如果a1 a2 an分别是第一对 第二对 和第 n 对点之间的距离 则 a1 a2 a
  • 在标准库中静态链接时如何支持动态插件?

    假设一个应用程序myapp exe是使用构建的g 它使用标志 static libstdc 这样就可以安装在没有环境的情况下libstdc so myapp exe还添加了对某些功能的插件支持plugf可以通过动态加载dlopen来自共享库
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • C# Linq 可以做组合数学吗?

    我有这个数据结构 class Product public string Name get set public int Count get set var list new List
  • 一些涉及类析构函数和删除运算符的内存管理问题?

    在阅读了一些教程后 我仍然不清楚 C 中内存管理的一些观点 1 当使用 new 运算符声明的类超出范围时 是否会调用其析构函数并释放内存 是否有必要调用删除运算符来释放类的内存并调用其析构函数 class Test void newTest
  • Global.asax 错误处理程序或自定义 IHttpModule 错误处理程序未捕获未处理的异常

    我有一个类 DPCal EventMove 的一种方法 我想限制使用角色的访问 我有一个 Global asax cs 错误处理程序和一个自定义 IHttpModule 错误处理程序 旨在捕获未处理的异常 并将它们 Server Trans
  • C# 编译器编译 .txt .obj .java 文件

    using System class Program public static void Main Console WriteLine Hello World Console ReadLine 我将文件另存为1 java 2 obj an
  • 使用std::begin()、std::end()将ArrayXd转换为stl向量,

    在我看来我应该能够使用std begin and std end 转换ArrayXd to std vector
  • RabbitMQ + Windows + LDAP 无需发送密码

    我正在尝试在 Windows 7 上使用 RabbitMQ 3 6 2 进行 LDAP 身份验证 授权 我已经在应用程序发送用户名 密码的情况下进行了基本身份验证 但密码位于我需要弄清楚如何进行的代码中避免 有没有人在不提供密码的情况下成功
  • 在 C++ 中将大型数据向量写入/读取到二进制文件

    我有一个 C 程序 它通过将 ascii 文件中的网格人口数据读取到大型 8640x3432 元素双精度向量中来计算给定半径内的人口 将 ascii 数据读入向量大约需要 30 秒 循环每列和每行 而程序的其余部分只需要几秒钟 我被要求通过
  • 如何使用字符串的值将字符串转换为 wstring?

    我是 C 新手 我有这个问题 我有一个名为 DATA DIR 的字符串 需要将其格式化为 wstring string str DATA DIR std wstring temp L s str Visual Studio 告诉我没有与参数

随机推荐