c++ - 模板特化或分离函数的语义

标签 c++ templates enums semantics

我正在围绕 C 库 libnetfilter_conntrack 创建一个 C++ 包装器,它使用函数 nfct_set_attr(...)。它需要一个 enum 来定义要设置的属性的类型,以及一个 void* 来传递数据(根据属性不同而不同)。由于这是 C++,我想让它成为类型安全的,所以我需要为每个属性类型提供单独的函数。然而,为了提高兼容性,我创建了一个 enum class,它定义了 libnetfilter_conntrack 中可用的所有属性类型。

我最初的想法是创建模板化的 set_attr(...) 函数,它根据需要设置的属性采用模板。例如:

template<attr_type, typename T> void set_attr(T); // designed to fail
template<> void set_attr<orig_ipv4_src, unsigned long>(unsigned long ip) {};

这种方法的优点是直接将 enum class 定义链接到函数,这可能会使逻辑更清晰一些。但我想到了另一个可能的选择,为每个属性使用单独的函数:

void set_orig_ipv4_src(unsigned long ip) {};

在函数内部,enum class 无论如何都会被使用(调用底层 C 例程),所以那些定义仍然存在。

以上两种方法哪个更有意义?使用模板版本是否存在任何固有问题?性能问题?

最佳答案

所写的模板方法确实有问题。考虑:

long ip = get_ip();
set_attr<orig_ipv4_src>(ip);

此代码无法编译。尽管 longs 可以转换为 unsigned longs,但我们还是回到了大概包含 static_assert(false) 的通用模板中。

有一种方法可以解决这个问题:

template<attrt ATTR>
struct attr_info {
  typedef void argtype;
};
template<>
struct attr_info<orig_ipv4_src> {
  typedef unsigned long argtype;
};
// etc.
template<attrt ATTR>
void set_attr(attr_info<ATTR>::argtype arg) {
  // set the attr
}

这将很好地进行类型提升。如果需要,它还可以让您以其他方式获取此信息。

不过,尽管它很漂亮,但我不确定这种方法比单独的函数有任何实际优势。也就是说,我不确定这能实现的事情是任何人都想做的事情。新接触该项目的人需要做更多的工作才能理解。

我建议查看旧的 c 代码,看看是否有人使用非文字第一个参数调用此函数。如果是这样,请确保他们正在做的事情在新系统中是可行的。如果没有,可能会使用单独的函数。

关于c++ - 模板特化或分离函数的语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20116056/

相关文章:

c++ - Rcpp 错误 : ‘unique_ptr’ is not a member of ‘std’

c++ - 使用带有 MFC CString 的 boost 字符串算法来检查字符串的结尾

java - 枚举样式工厂作为 Java 中的内部枚举

java - 序列化枚举

c# - 当我只有枚举的类型时,如何获取枚举的整数值

c++ - 使用main中的新作品创建动态数组的C++代码,但不能作为单独的函数工作

c++ - 如果我删除了 const,为什么这个使用 boost::shared_ptr 的调用不能在 C++ 中编译?

c++ - 模板:静态类型还是动态类型?

c++ - 如何将模板构造函数特化移动到 cpp 文件?

C++为什么模板标题底部的#include?