惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
I
InfoQ
H
Help Net Security
GbyAI
GbyAI
博客园 - 叶小钗
Recent Announcements
Recent Announcements
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
Y
Y Combinator Blog
L
LangChain Blog
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
博客园 - Franky
D
Docker
Jina AI
Jina AI
罗磊的独立博客

博客园 - gearslogy

PCG建筑开发 Houdini HDANC -> HDA Houdini NC HDA -> HDA PBRT 蒙特卡洛采样 BRDF是BSSRDF的一个特殊形式 来自伟大的AI UE5.7编辑器扩展 PBRT中的RayDifferentials Unreal Fur 假毛发 草地 Grass PBRT v2中,隐士表面、三角形的dpdu dpdv dndu dndv 思考 Houdini Vulkan HeightBlend 高度混合 Indexmap Vulkan矩形绘制顺序小坑 C++ Runtime Reflection QML NextQT 随手 HDK门格海绵 clang reflection Master LLVM GEP Qt问题记录 现代CPP设计模式 CPP2nd CRTP Facade 模式 billboard暴力实现 Fibonacci各种玩法 ubuntu升级编译器
类型擦除TypeErase
gearslogy · 2023-02-12 · via 博客园 - gearslogy

来自CppCON2022

通过极其简单的方法实现:

头文件:

#pragma once

#include <iostream>
#include <memory>
#include <vector>
struct CommandConcept
{
    virtual ~CommandConcept() = default;
    virtual void do_exec() = 0;
    virtual void do_info() const = 0;
};

template< typename CommandT >
struct CommandModel : public CommandConcept
{
    CommandModel(CommandT cmd)
        : cmd_{ std::move(cmd) }
    {}
    void do_exec() override { adl_exec(cmd_);}
    void do_info() const override { adl_info(cmd_); }
    CommandT cmd_;
};


inline void execALL(const std::vector<std::unique_ptr<CommandConcept>> & cmds){
    for (auto & cmd : cmds){
        cmd->do_exec();
    }
}
inline void infoALL(const std::vector<std::unique_ptr<CommandConcept>>& cmds){
    for (const auto& cmd : cmds){
        cmd->do_info();
    }
}

源:

#include "TypeErase.h"
using namespace std;

struct CMD1 {
    void exec() { std::cout << "exec 1" << std::endl;}
    void info() const { std::cout << "I'm CMD1" << std::endl; }
};
struct CMD2 {
    void exec() { std::cout << "exec 2" << std::endl;}
    void info() const { std::cout << "I'm CMD2" << std::endl; }
};
struct CMD3 {
    void exec() { std::cout << "exec 3" << std::endl; }
    void info() const { std::cout << "I'm CMD3" << std::endl; }
};


// adl exec
void adl_exec(CMD1& cmd) {
    cmd.exec();
}
void adl_exec(CMD2& cmd) {
    cmd.exec();
}
void adl_exec(CMD3& cmd) {
    cmd.exec();
}

// adl info
void adl_info(const CMD1& cmd) {
    cmd.info();
}
void adl_info(const CMD2& cmd) {
    cmd.info();
}
void adl_info(const CMD3& cmd) {
    cmd.info();
}


int main()
{
    using CMDS = std::vector<std::unique_ptr<CommandConcept>>;

    std::unique_ptr<CommandModel<CMD1> > cmd1 = std::make_unique<CommandModel<CMD1>>(CMD1());  // also auto cmd1 = std::make...
    std::unique_ptr<CommandModel<CMD2> > cmd2 = std::make_unique<CommandModel<CMD2>>(CMD2());
    std::unique_ptr<CommandModel<CMD3> > cmd3 = std::make_unique<CommandModel<CMD3>>(CMD3());

    CMDS cmds;
    cmds.emplace_back(std::move(cmd1));
    cmds.emplace_back(std::move(cmd2));
    cmds.emplace_back(std::move(cmd3));
    execALL(cmds);
    infoALL(cmds);
}

可以看到 cmds可以插入不同的类。CMD1,CMD2,CMD3类中本质没有虚函数。