【问题标题】:C++ compile time checking of type equality in a preprocessor directiveC++ 编译时检查预处理器指令中的类型相等性
【发布时间】:2021-08-10 18:12:37
【问题描述】:

我想在 C++11 的编译时检查两个 POD 类型是否相等。我正在尝试 #define 适合 Float_T 类型的函数名称。这是我尝试过的:

#include <type_traits>

using Float_T = double;
// using Float_T = float;

#if is_same<Float_T, double>::value
    #define LOG2  log2
#else
    #define LOG2  log2f
#endif

 g++ complains:  error: extra text after expected end of preprocessing directive
  #if is_same<Float_T, double>::value
                     ^

谁能建议一种方法来做到这一点?

【问题讨论】:

  • 你的意思是c++11吗?
  • C 还是 C++?编译时常量在编译时使用,而不是解析时使用。
  • 顺便说一句,如果你使用std::log2,函数已经重载,所以这个技巧没用。
  • 您不能使用 STL 功能 (is_same) 作为预处理器宏的条件。 C 预处理器对 STL 一无所知,也无法评估它。况且整个sn-p看起来像是徒劳的运动,闻着XY问题。
  • 有很多方法可以做这样的事情。您要解决的实际问题是什么?

标签: c++ c++11 c-preprocessor typetraits


【解决方案1】:

宏在source code is being parsed, much before compilation kicks in 时被评估,这就是为什么它只不过是一个简单的复制粘贴机制。所以,做这样的事情:

#if is_same<Float_T, double>::value
    #define LOG2  log2
#else
    #define LOG2  log2f
#endif

实际上是不可能的,因为在整个编译过程中,is_same#if 在不同的时间被评估。你可以做的就是把宏变成一个函数,像这样:

#include <type_traits>
#include <cmath>

using Float_T = double;

template <typename T = Float_T>
typename std::enable_if<std::is_same<T, double>::value, double>::type LOG2(Float_T const& x) {
    return log2(x);
}

template <typename T = Float_T>
typename std::enable_if<!std::is_same<T, double>::value, float>::type LOG2(Float_T const& x) {
    return log2f(x);
}

// ...

【讨论】:

  • 应该是LOG2(Float_T const&amp; x),否则T是从参数推导出来的,而Float_T是不用的。
  • 因为loglogf 都没有定义为constexpr,所以这些函数永远不能作为常量表达式求值。这里的constexpr 毫无意义。如果我没记错的话,一个标记为constexpr 的函数永远不会被评估为一个常量表达式,这会使程序格式错误,不需要诊断。
  • @Ruks 感谢您对使用预处理器的愚蠢尝试做出的温和回应。我想如果我想使用预处理器根据 Float_T 的实际类型编译或不编译某些代码块,我唯一的选择是将 Float_T 定义为宏(#define),而不是别名或 typedef。对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多