【问题标题】:How to use std::is_same to generate compile time errors?如何使用 std::is_same 生成编译时错误?
【发布时间】:2016-07-05 13:31:24
【问题描述】:

我正在使用第三方 API,其中包含一个包含一组 typedef 的头文件。在过去的 4 年中,一些 typedef 发生了细微的变化(例如,在无符号/有符号之间切换,从 int 更改为 long 等)。

我想在我的代码中添加编译时检查,以便我知道特定的 typedef 是否已更改。我正在考虑添加如下内容:

#if !std::is_same<::ApiType, int>::value
#error Type has changed
#endif

当我在各种 typedef 中尝试这个时,我发现总是抛出编译错误。

我设置了一个小型控制台程序,它显示了同样的问题(即预处理器使用总是错误的)但在预处理器之外很好:

#include "stdafx.h"
#include <Windows.h>
#include <type_traits>

int main()
{
#if std::is_same<int, int>::value
  const auto aa = 14; // omitted
#else
  const auto bb = 17;
#endif

#if std::is_same<::DWORD, int>::value
  const auto cc = 14; // omitted
#else
  const auto dd = 17;
#endif

  const auto a = std::is_same<int, int>::value; // true
  const auto b = std::is_same<::DWORD, int>::value; // false
  const auto c = std::is_same<::DWORD, unsigned long>::value; // true

  return 0;
}

我正在使用 Visual Studio 2015。

我如何对预期的类型实施这样的编译时检查(特别是如果类型不同则产生编译时错误)?

【问题讨论】:

  • 虽然现在已经不是这样了,但您应该真正将预处理器和编译器视为两个独立的实体,几乎是两个在源代码上分别运行的不同程序。预处理器首先在源代码上运行并创建编译器看到并处理的translation unit。因此,预处理器不了解实际的 C++ 语言,包括像 std::is_same 这样的实体,它是标准库的一部分。

标签: c++ visual-c++ std c-preprocessor


【解决方案1】:

预处理器对类型一无所知。 (提示:它运行 before 编译,因此是“pre”。)

你想要的是static_assert。例如:

static_assert(std::is_same<::ApiType, int>::value,
              "Type has changed");

虽然,既然是断言,或许应该说‘has not’。

你几乎可以把它放在任何地方,甚至在任何函数之外。

【讨论】:

  • 我一般#define STATIC_ASSERT(e) static_assert( e, #e "// is required" )。对于 C++17,有单参数 static_assert。但我认为,更具可读性的消息仍然足以继续使用宏。
  • 我通常会手工制作一个清晰易懂的信息,也许会有一些关于如何解决问题的好技巧,但每个人都有自己的想法。 ;)
猜你喜欢
  • 2023-04-06
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-16
相关资源
最近更新 更多