【问题标题】:determine whether wchar_t is a built-in type or alias确定 wchar_t 是内置类型还是别名
【发布时间】:2021-06-01 04:59:20
【问题描述】:

是的,wchar_t 应该是 C++ 中的内置类型;不幸的是,某些(非常)旧的编译器并非如此。 ????

是否有(特定于编译器,例如 GCC/g++)的方法来确定 wchar_t 是内置类型(关键字)还是 typedef?原因是判断f(wchar_t)是否可以重载;如果wchar_ttypedef,它将(很可能)与f(uint16_t)f(uint32_t) 相同。

Microsoft Visual C++ 有 _NATIVE_WCHAR_T_DEFINED,所以我可以写:

#include <stdint.h>

#if defined(_MSC_VER)
   #define MY_PROJECT_wchar_t_is_built_in_ (_NATIVE_WCHAR_T_DEFINED == 1)
#else
   #define MY_PROJECT_wchar_t_is_built_in_ 1
#endif

void f(uint16_t ch_utf16) { /* UTF-16 processing */ }
void f(uint32_t ch_utf32) { /* UTF-32 processing */ }

#if MY_PROJECT_wchar_t_is_built_in_
   #include <type_traits>
   void f(whcar_t ch_)
   {
      using wchar_t_type = std::conditional<sizeof(wchar_t) == sizeof(uint32_t), uint32_t, uint16_t>::type;
      #ifdef _WIN32
      static_assert(sizeof(wchar_t_type) == sizeof(uint16_t), "wchar_t should be 16-bits on Windows.");
      #endif
      const auto ch = reinterpret_cast<wchar_t_type>(ch_);
      f(ch);
   }
#endif

Extensive TMP 可能不起作用(例如,std::enable_if)...因为它是一个旧的编译器首先导致了问题!

【问题讨论】:

  • is_same_v&lt;wchar_t, uint16_t&gt; || is_same_v&lt;wchar_t, uint32_t&gt; 怎么样?
  • Ayxan 有一个实用的答案,但所提出的问题似乎存在一些无法解决的问题。例如。如果 wchar_t__wchar_t 的 typedef 怎么办? uint16_t 绝对是某种形式的 typedef(可能是 using),它甚至可能是 wchar_t 的 typedef!所以即使你有一个技术上正确的答案,它也可能没有用。
  • @Ðаn:当然,对于 GCC,您可能会找到答案,但您可以直接测试 GCC 版本。我认为 GCC 将其修复在 2.95.2 左右 - 自 C++98 以来它一直是一种类型。
  • @Ðаn 没有这样的事情。您可以期望的最好的结果是一些晦涩的模板技巧,它不能很好地与您的预处理器示例配合使用。只测试主要编译器的版本(gcc、clang、msvc、icc,以及您支持的其他任何东西)并称之为一天怎么样?
  • @M.M 从这个问题的第一句话开始,我假设 OP 正在使用不符合标准的古代编译器。

标签: c++ visual-c++ typedef wchar-t


【解决方案1】:

Ayxan Haqverdilisuggestion 在评论中使用templatesizeof() 解决了我的问题。 (它还说明了为什么需要足够的关于“为什么?”的上下文。)

我的代码现在是:

void f_(uint16_t ch_utf16) { /* UTF-16 processing */ }
void f_(uint32_t ch_utf32) { /* UTF-32 processing */ }

template<typename T>
void f(T ch_)
{
    static_assert(sizeof(T) == sizeof(wchar_t), "T should be wchar_t");

    if (sizeof(T) == sizeof(uint16_t))
    {
        const auto ch = reinterpret_cast<uint16_t>(ch_);
        f_(ch);
    }
    else if (sizeof(T) == sizeof(uint32_t))
    {
        const auto ch = reinterpret_cast<uint32_t>(ch_);
        f_(ch);
    }
    else
    {
        throw ...;
    }
}

【讨论】:

  • reinterpret_cast&lt;uint16_t&gt;(ch_) 如果ch 是另一个整数或字符类型,则格式不正确(只有指针可以重新解释为整数)
  • reinterpret_cast 应该是 static_cast 我猜。
猜你喜欢
  • 1970-01-01
  • 2017-10-13
  • 2011-03-11
  • 1970-01-01
  • 2017-10-12
  • 2010-12-11
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
相关资源
最近更新 更多