c++ - 如何防止手动实例化所有模板类型?

标签 c++ templates

我有一个功能 Foo得到两个模板参数 L3HdrTypeL4HdrType .我收到一个数据包并解析它,然后需要调用该函数。我的代码目前看起来像:

ParsedPacket parsed_packet = parser.Parse(packet);
if (parsed_packet.ip_version() == IPv4 && parsed_packet.ip_proto() == TCP)
  Foo(parsed_packet.L3Header<ipv4_hdr>(), parsed_packet.L4Header<tcp_hdr>());
if (parsed_packet.ip_version() == IPv6 && parsed_packet.ip_proto() == TCP)
  Foo(parsed_packet.L3Header<ipv6_hdr>(), parsed_packet.L4Header<tcp_hdr>());
if (parsed_packet.ip_version() == IPv4 && parsed_packet.ip_proto() == UDP)
  Foo(parsed_packet.L3Header<ipv4_hdr>(), parsed_packet.L4Header<udp_hdr>());
if (parsed_packet.ip_version() == IPv6 && parsed_packet.ip_proto() == UDP)
  Foo(parsed_packet.L3Header<ipv6_hdr>(), parsed_packet.L4Header<udp_hdr>());
我的问题是,有没有办法减少这种代码重复?类似的东西:
Foo<parsed_packet.GetL3HeaderType(), parsed_packet.GetL4HeaderType()>(...);
这显然不起作用,因为在编译时不知道给定数据包的 header 类型。
重复的根源在于两个不同的 if 语句正在检查 IPv4并将其映射到 ipv4_hdr .如果我可以在代码中的一处指定 IPv4映射到 ipv4_hdr然后它会使代码随着选项的数量线性增长而不是指数增长,因为我可以以某种方式编写:
if (parsed_packet.ip_version() == IPv4) {
  using L3HeaderType = ipv4_hdr;
}
...
Foo<L3HeaderType, L4HeaderType>(...)
请注意,我的实际代码需要支持不止 4 种情况,因此实际代码比这里的示例要丑陋得多,因为 if 语句的数量随着 header 的数量呈指数增长。

最佳答案

如果继承和运行时多态性不是一个选项,您可以通过执行一些涉及 lambda 的杂技来解耦两个模板参数的推导:

template <typename T> struct foo {};    
template <typename T> struct bar {};

// the function to be called
template <typename A, typename B>
void foobar( foo<A> f, bar<B> b) {}

// bind the first parameter
template <typename T>
auto make_foofoo (foo<T> f) {
    return [f](auto bar){ foobar(f,bar); };
}

// select second type here
template <typename F>
void do_the_actual_call(F f, int y) {
    if (y == 1) f(bar<int>{});
    if (y == 2) f(bar<double>{});
}


int main() {
    // the "conditions"
    int x = 1;
    int y = 2;

    // select first type here
    if (x == 1) {
        auto foofoo = make_foofoo(foo<int>{});
        do_the_actual_call(foofoo,y);
    } else if (x == 2){
        auto foofoo = make_foofoo(foo<double>{});
        do_the_actual_call(foofoo,y);
    }
}
它仍然是重复的代码,但它缩放为 x + y不再是 x * y .

关于c++ - 如何防止手动实例化所有模板类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64263462/

相关文章:

c++ - 重载运算符上的 bad_lexical_cast 异常 ">>"

c++ - 为什么绑定(bind)到引用类型时 "const auto [x, y]"的行为不符合预期?

django - 如何在 django 模板中显示代码片段, "|safe"过滤器没有帮助

C++:使用模板继承类

c++ - c++-通过抽象模板基类接口(interface)指针访问派生类方法,而接口(interface)中没有显式类型

c++ - 如何使 =NULL 在 SQLite 中工作?

c++ - 如何使用 C++11 lambda 作为 boost 谓词?

c++ - 继承返回 *this 的成员函数

c++ - 通用引用与常量引用优先级?

c++ - 从 nullptr 推导的指向模板类型?