判断 wchar_t 是内置类型还是别名
determine whether wchar_t is a built-in type or alias
是的,wchar_t
应该是 C++ 中的内置类型;不幸的是,某些(非常)旧的编译器并非如此。
是否有(特定于编译器,例如 GCC/g++)的方法来确定 wchar_t
是内置类型(关键字)还是 typedef
?原因是判断f(wchar_t)
是否可以重载;如果 wchar_t
是 typedef
,它将(很可能)与 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
广泛的 TMP 可能无法工作(例如,std::enable_if
)...因为它是一个旧的编译器首先导致了问题!
Ayxan Haqverdili's suggestion 在评论中使用 template
和 sizeof()
解决了我的问题。 (它还说明了为什么关于“为什么?”的足够上下文是必要的。)
我现在的代码是:
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 ...;
}
}
是的,wchar_t
应该是 C++ 中的内置类型;不幸的是,某些(非常)旧的编译器并非如此。
是否有(特定于编译器,例如 GCC/g++)的方法来确定 wchar_t
是内置类型(关键字)还是 typedef
?原因是判断f(wchar_t)
是否可以重载;如果 wchar_t
是 typedef
,它将(很可能)与 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
广泛的 TMP 可能无法工作(例如,std::enable_if
)...因为它是一个旧的编译器首先导致了问题!
Ayxan Haqverdili's suggestion 在评论中使用 template
和 sizeof()
解决了我的问题。 (它还说明了为什么关于“为什么?”的足够上下文是必要的。)
我现在的代码是:
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 ...;
}
}