【问题标题】:Template parameter vs function argument模板参数与函数参数
【发布时间】:2021-12-23 15:07:55
【问题描述】:

我正在编写一些代码并意识到我不知道哪个更好用。每个的好处/缺点是什么?我目前正在使用带有 const uint16_t 的那个,因为我认为模板化它会通过创建独特的函数签名来扩展二进制文件。提前感谢任何想要帮助解释这一点的人!

template<typename T, uint16_t response_size>
T get_endpoint_value(const uint16_t endpoint_id)

对比

template<typename T, uint16_t response_size, uint16_t endpoint_id>
T get_endpoint_value()

对比

template<typename T>
T get_endpoint_value(serial::Serial* serial, 
const uint16_t endpoint_id, const uint16_t response_size)

其中endpoint_id 只是一个被复制到缓冲区中的值。 response_size 用于在串行数据传输期间调整uint_t buffer[response_size] 的大小。

【问题讨论】:

  • 您已经列出了所有参数。如果您有大量不同的模板参数组合,编译器会为这些集合中的每一个生成或多或少相同的代码,这可能会浪费您的内存。但是:如果函数中的所有东西都可以被优化掉并内联,结果可能是代码变小了。但这一切都取决于编译器、优化器级别和所有代码复杂性。查看结果的唯一方法:试试看!

标签: c++ c++11 templates


【解决方案1】:

基于模板的版本允许编译器inline 调用,因为函数的地址在编译时是已知的。您无法在运行时更改模板参数的值的缺点。

所以如果你想在runtime中改变参数,你必须使用参数而不是模板参数。请注意,runtime 是指您的应用程序正在运行的时间,而 compile time 是指您的应用程序正在编译的时间。如果在运行时不需要模板并且response_size/endpoint_id 的值在编译时是固定/已知的,我会使用模板

【讨论】:

    【解决方案2】:

    总结:使用函数参数,除非您有特殊原因不这样做。

    如果你在编译时不知道你的参数,你就别无选择——你不能在模板参数中使用它。假设你在编译时就知道了。

    如果函数太小以至于编译器内联它,那么函数参数和模板参数的结果是相同的。如果不是,那么传递函数参数所花费的时间很可能可以忽略不计,但额外模板实例化导致的代码膨胀的影响可能很重要。

    现在,偏爱模板参数的特殊原因:

    1. 这可以让您避免函数内部的动态内存分配。例如,如果您需要一个大小为response_size 的缓冲区,您可以将其声明为std::vector&lt;char&gt; buf(response_size);。但是,如果response_size 是模板参数,则可以将其声明为std::array&lt;char, response_size&gt; buf;,避免动态内存。
    2. 您知道仅可用于编译时常量的重要编译时优化。例如,整数除法很慢,但如果除数是编译时常量,它可能会被一系列更快的操作替换。

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2016-04-27
      • 2013-08-02
      • 2023-03-26
      • 1970-01-01
      • 2012-06-18
      相关资源
      最近更新 更多