当前位置: 首页 > 知识库问答 >
问题:

根据运行时参数避免模板实例化的代码重复

陶琦
2023-03-14

我正在使用一个由其他人编写的C++库,它(不幸的是imo)实现了几个封装在类中的算法,这些类的行为可以通过作为模板参数传递的参数(参数通常也是类)进行微调。例如,可能有这样一个类模板:

template<typename Param1, typename Param2, typename Param3>
class Foo {
  // ...
};

我想用这个库编写一个程序,它需要根据运行时信息创建foo的实例。我的问题是,假设有n1N2n3有效类型可以为param1param2param3传递,那么当我想实例化foo的不同spezialization时,我可能需要在代码中的某个位置创建多达n1 x N2 x n3分支。例如,在运行时,通过用户输入给我三个字符串,每个字符串决定foo的模板参数应该是哪种类型,那么我需要执行如下操作:

std::string s1, s2, s3;

// instantiate s1, s2, s3 from user input

if (s1 == "Param1_1" && s2 == "Param2_1" && s3 == "Param3_1") {
  Foo<Param1_1, Param2_1, Param3_1> foo;
} else if (s1 == "Param1_1" && s2 == "Param2_1" && s3 == "Param3_2") {
  Foo<Param1_1, Param2_1, Param3_2> foo;
}

// ...

其中param1_1param1的有效类型,以此类推。我如何更优雅地实现这一点?(理想情况下只使用C++11或至多C++17特性)。

共有1个答案

龙骏
2023-03-14

您可以对每种类型使用std::variant(C++17),并对分派使用std::visite

template <typename T> struct Tag{ using type = T;};

std::variant<Tag<T1>, Tag<T2>, Tag<T3>/*..*/> getType(const std::string& s)
{
    if (s == "Param1") { return Tag<T1>{}; }
    else if (s == "Param2") { return Tag<T2>{}; }
    // ...
}

void bar(const std::string& s1, const std::string& s2, const std::string& s3)
{
    auto v1 = getType(s1);
    auto v2 = getType(s2);
    auto v3 = getType(s3);

    std::visit([](auto t1, auto t2, auto t3)
              {
                  Foo<typename decltype(t1)::type,
                      typename decltype(t2)::type,
                      typename decltype(t3)::type> foo;
                  /*..*/
               }, v1, v2, v3);
}
 类似资料:
  • 我目前正在开发一个Android应用程序,我使用Firebase(实时功能)作为后端服务。此外,我开发了这个功能,如下所示。 扩展代码工作得很好,它检查现有数据并显示Toast消息,但在数据仍进入数据库后,我想消除重复数据。

  • 介绍 任何编程都提出代码复用,否则话每次开发一个新程序或者写一个新功能都要全新编写的话,那就歇菜了,但是代码复用也是有好要坏,接下来的两篇文章我们将针对代码复用来进行讨论,第一篇文避免篇,指的是要尽量避免使用这些模式,因为或多或少有带来一些问题;第二排是推荐篇,指的是推荐大家使用的模式,一般不会有什么问题。 模式1:默认模式 代码复用大家常用的默认模式,往往是有问题的,该模式使用Parent()的

  • 实时代码模板的介绍 上图 Gif 演示为最好的介绍 Live Templates。 实时代码模板需要字符串前缀,如 Gif 演示中,在输入 sys 后生成一段输出语句,其中 sys 前缀是我自己设置的。 实时代码模板支持变量参数设置,如 Gif 演示中,在输入 temp1 的时候,后面自动也生成了一个 temp1,这是因为两者的变量名是一致的,所以我设置了一个变量值内容之后,相同变量值的内容也会跟

  • 本文向大家介绍Vue模板语法中数据绑定的实例代码,包括了Vue模板语法中数据绑定的实例代码的使用技巧和注意事项,需要的朋友参考一下 1.单项数据绑定  通过浏览器 REPL 环境可以进行修改 app.input_val = 'Vue' 我们通过 vue 对象修改数据可以直接影响到 DOM 元素,但是,如果直接修改 DOM 元素,却不会影响到 vue 对象的数据;我们把这种现象称为 单向数据绑定 ;

  • 我有一个调用外部API的Java程序(在下面的代码中),有时我想避免调用此API,而是返回预先构造的响应(由生成)。 所以,我在大多数方法中都复制了这种构造: 有哪些选项可以避免在任何地方重复这个try/catch块?重要的是,如果抛出异常或返回null,则必须调用。

  • 函数模板、成员函数模板、或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何这样的专门化,翻译单元的末尾也被认为是实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中具有实例化点。如果两个不同的实例化点根据一个定义规则赋予一个模板专门化不同的含义,则程序是格式不良的,不需要诊