【问题标题】:Template instead of macro as class field模板而不是宏作为类字段
【发布时间】:2021-04-13 12:17:00
【问题描述】:

我正在尝试 modernize 我的代码,并借助一些整洁的建议。假设我有这样的课程:

class Config {
public:
  static constexpr auto FIELD1 = "FIELD1";
  static constexpr auto FIELD2 = "FIELD2";  
};

由于字段列表越来越大,我有一个简单的宏:

#define CONFIG_PARAM(param) \
  static constexpr auto param = #param;

这可以将我的代码转换为更少样板的版本:

class Config {
public:
  CONFIG_PARAM(FIELD1)
  CONFIG_PARAM(FIELD2)
};

而且效果很好。除了我收到来自 clang-tidy 的警告说我应该为此考虑一个 constexpr 模板函数。是否有一个我不知道的神秘功能可以从模板中创建像这样的成员变量?

【问题讨论】:

  • 你能提供来自clang-tidy的消息吗?
  • 恕我直言,没有宏会更干净(尤其是在头文件中)
  • 你这样做的方式很好。不要修复没有损坏的东西,也不要让事情变得更复杂。
  • @Quimby Function-like macro 'CONFIG_PARAM' used; consider a 'constexpr' template function [clang-tidy: cppcoreguidelines-macro-usage]
  • 看起来 clang-tidy 对这种情况有点乐观——你不能不使用宏来字符串化标识符。

标签: c++ templates c++20


【解决方案1】:

它的暗示是这样的:

template <T> constexpr T* config_param(const T* v) {
    return v;
}

class Config {
public:
    auto FIELD1 = config_param("FIELD1");
}

我会忽略它,让它保持原样。

【讨论】:

  • 啊,所以没有隐藏的宝石让我的代码更加难以阅读。多么令人失望!我想我会坚持使用// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)。谢谢。
  • @LeśnyRumcajs 它在您需要使用预处理器进行数学运算的情况下很有用,您现在可以使用 constexpr 函数来完成。它只是不够聪明,无法判断什么时候有用,什么时候没用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
相关资源
最近更新 更多