【问题标题】:Is it correct to turn "normal" parameters into templatized ones? [closed]将“正常”参数转换为模板化参数是否正确? [关闭]
【发布时间】:2014-02-16 00:08:27
【问题描述】:

如果函数的参数在编译时已知,那么将其转为模板参数是否正确

以如下代码为例:

template<typename ... P> void
    LOG
    ( const severity_level & l , const P & ... p )
    {
        // Take the parameters from 'p' and use it to construct a message.
        // Then, prepend a string depending on the severity level specified.
    }

由于严重性级别始终是编译时常量,我可以这样做:

template<severity_level L , typename ... P> void
    LOG
    ( const P & ... p )
    {
        // Call me like this:  LOG<debug>("this is a debugging message")
    }

只需对源代码稍加修改,就可以去掉一个参数。这个解决方案有什么缺点吗,还是没问题?

最好的问候, 卡尔里什

P.S.:这样做的另一个好处是更容易在编译时过滤,在此示例中,记录调用。

【问题讨论】:

  • 您自己提到了缺点:1)必须在编译时知道,2)不再有“一个记录功能”。请注意,调用站点当然会在编译时知道严重性级别,但模板版本禁止在日志管道中编写通用代码anywhere
  • @DanielFrey 你是对的,对不起。已更正。
  • @a.lasram 是一个示例枚举。关于参考,我不明白你的意思。 FWIW,我刚刚修正了一个错误(将 typename L 更改为 severity_level L)。
  • 嗯,这取决于用例:/ ...对于您给出的示例,恕我直言,这是一个坏主意(看看@TimothyShields 的答案)。

标签: c++ templates c++11 parameters parameter-passing


【解决方案1】:

我可以想象有人想要编写如下代码。

severity_level level = none;
if (discrepancy > .05)
{
    level = fatal;
}
else if (discrepancy > .01)
{
    level = warning;
}

if (level != none)
{
    //Taking some liberty with the printf-like signature...
    LOG(level, "Discrepancy in thingamabob: %f", discrepancy);
}

所以使用模板化方法是个坏主意。

【讨论】:

  • 可以通过使用函数指针轻松解决;)
  • @PlasmaHH“轻松”哈哈
  • 我从来没有真正看到需要这种类型的使用。您可以将日志移动到 if 语句中,然后提供不同严重级别的不同信息。
【解决方案2】:

除了仅限于编译时值之外,非类型模板参数仅限于某些类型:整数、枚举、指针、左值引用、指向成员的指针或std::nullptr_t 类型。因此,如果参数不是其中之一,则无法将其转换为模板参数。当然,严重性级别可能是一个枚举,所以这可能没问题。

要记住的一点是,即使您的代码现在符合要求,将来您也可能想要进行更改,如果您以这种方式约束自己,可能会更难。例如,您最终可能希望根据用户选项以不同的严重性级别制作一些消息日志。

除非您能确定具体的好处,否则您应该避免进行更改。

【讨论】:

    猜你喜欢
    • 2019-09-27
    • 2021-09-02
    • 1970-01-01
    • 2015-01-16
    • 2015-05-13
    • 2011-11-30
    • 2021-04-09
    • 1970-01-01
    相关资源
    最近更新 更多