一次只需要一个指向不同类型的指针的最佳方法是什么?

如何解决一次只需要一个指向不同类型的指针的最佳方法是什么?

我处于一种需要将指向未知类型对象的指针作为另一个类的成员的情况。 但是有效对象类型的列表在编译时是已知的。

说我有

// A class templated on T
template<class T> class obj;

// Now assume there are some objects of types obj<...> somewhere else
obj<int> obj1;
obj<double> obj2;

// Now,manager needs to create a pointer for these objects
// in a specific manner at construction-time

// Say,we have to choose a canonical object (and set the other as secondary)

// manager shouldn't be templated on T because It needs
// to have multiple members of type obj<...>
template<class R>
class manager
{
    shared_ptr<...> canObjPtr;
    shared_ptr<...> secObjPtr;
 public:   
    // once set,canonical obj is not expected to change
    explicit manager(string canonicalObj);
}

我该如何实现?

一些最初的想法并没有真正起作用:

  1. 我能想到的最有前途的方法是将T1和T2模板参数添加到管理器并按如下方式构造:manager<R,obj<int>,obj<double>>()。我觉得我应该在构造管理器之前使用静态函数抓取“ canonicalObj”字符串,然后决定由哪个管理器创建manager<R,obj<double>>manager<R,obj<double>,obj<int>>

  2. 如何直接在obj1 and obj2对象上“模板化”管理器。看起来可行吗?请注意,我可以向管理器中添加模板参数,因为它与某些运行时选择机制有关,该机制不喜欢使用多参数模板。

  3. 创建2个成员指针,而不是2个成员指针(请参阅下文,但这太糟糕了,肯定会使我为之疯狂:在使用任何一个指针之前,必须始终检查一个指针是否为空)

template<class R> manager
{
    sharedPtr<obj<int>> canObjPtrI;
    sharedPtr<obj<float>> canObjPtrF;

    // same for secObjPtr above
 public:
    explicit manager(string canonicalObj);
}
  1. std::any and std::variant(及其升压等效项)是不可能的,因为我想继续使用c ++ 11并且不能按策略使用升压。如果我违反其中一项规则,我会考虑升级到c ++ 17。

  2. 例如,我认为使用shared_ptr<void>不会带来任何好处,因为无论如何我都必须将指针强制转换为正确的类型,并且不能使用空指针。

  3. 对于union也可以这样说。与3相比几乎没有改善。

此外,如果您将其视为潜在的设计问题,请不要退缩。我邀请您指出您发现的任何缺陷/改进。

[编辑] 此代码试图执行的操作是...

基本上,如上所述,我需要从预先构造的obj<int> and obj<double>对象列表中选择一个规范的和辅助对象:

基于用户输入,类应决定一个规范对象,并根据此决定执行计算。我已经具有通过其名称(字符串)来引用这些对象的工具。唯一的问题是它们的类型不同,并且使它们从基类继承会限制我仅使用该基类的接口(对吗?)。

评论中要求的最小示例

// A base template for objects defines common
// and possibly different interface.
template<class T> class objBase
{
protected:
    field<T> f_;

public:

    // Public data type
    using fieldType = field<T>;

    // New selects from "Registered childs of objBase"
    // at runtime
    static shared_ptr<objBase>::New() const;

    // Pure virtual to update the obj
    virtual void update() = 0;

    // Const-Access to field
    const field<T>& getField() const;
};

// Created objects are also registered automatically to a database
// i.e. I can get (const-)refs to them by querying the database
shared_ptr<objBase<int>> obj1 = objBase<int>::New();
shared_ptr<objBase<int>> obj2 = objBase<int>::New();
shared_ptr<objBase<float>> obj3 = objBase<float>::New();

// In manager,something like this needs to happen
template<class R>
class manager
{
private:
    // Read 2 target obj names from user input
    pair<string,string> objNames;

    // Possible types for requested objs:
    // obj_a,obj_b : both objBase<int> or both objBase<float>
    // or they can have different types 
    // But we essentially need only:
    pointer<...> canonicalObj;
    pointer<...> secondaryObj;

    // These should be used like this
    void useObjField() const
    {
        // Not using auto for clarity
        const decltype(*canonicalObj)::FieldType& objField
            = canonicalObj->getField();
        for(int i=0; i < objField.size(); ++i)
        {
            // Loop through elements and use them for some calculations
            // Related to other fields in manager
        }
    }
};

解决方法

std::anystd::variant(以及它们的boost等效项)是不可能的,因为我想继续使用c ++ 11并且不能按策略使用boost。

仍然没有问题:您可以使用mpark::variant-它与C ++ 11兼容。还有其他这样的变体类实现。如果您想使用类似any的课程(不建议使用),请尝试使用linb::any-同样的想法;与C ++ 11兼容。

IIANM,这两个都是仅标头的库(忽略测试/示例程序),因此您甚至不需要任何复杂的安装;您可以获取标题的最新版本,或者对其进行超级组织,使用CMake正确构建和安装它们,然后使用CMake find_package()命令定位它们。

最后,“限定联合”将是使用变体的粗略选择。变体本质上是一个并集和一个变量,该变量告诉您​​并集中的哪些类型是活动的。为了简化使用和安全性,我不建议您这样做-但这可能意味着更少的代码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res