你能在编译时将__func__转换成wchar_t []吗?

use*_*587 8 c++ visual-c++

所以我有这段代码

wchar_t funcName[] = __FUNCTIONW__;
Run Code Online (Sandbox Code Playgroud)

但问题__FUNCTIONW__是,当我想要的只是函数名称时,它在名称中有类信息.现在__FUNCTIONW__只是调用_CRT_WIDE(__FUNCTION__)让我觉得我可以调用_CRT_WIDE(__func__)但是会出现错误"标识符L__func__未定义"

__func__是一个隐式声明的标识符,当在函数内部使用时,它会扩展为包含函数名的字符数组变量.它被添加到C99的C中.从C99 §6.4.2.2/ 1:

标识符__func__由翻译器隐式声明,就像紧跟在每个函数定义的左括号之后的声明一样

static const char __func__[] = "function-name";
Run Code Online (Sandbox Code Playgroud)

出现了,其中function-name是词法封闭函数的名称.此名称是函数的简单名称.

我认为这意味着__func_不是宏,它与预处理无关?

有没有其他方法可以在编译时获得wchar_t数组?

Aco*_*gua 3

正如您已经引用的 C 标准(实际上,这是一个不好的标准,您需要 C++ 标准,但在那里您发现了相同的...):

static const char __func__[] = "function-name";
Run Code Online (Sandbox Code Playgroud)

现在,您遇到了与要在编译时转换任意其他数组相同的问题,例如:

char buffer[16];
// convert to wchar_t[16]?

int array[4];
// convert to double[4]?
Run Code Online (Sandbox Code Playgroud)

数组的类型是int[4]. 那就是修复。它在内存中占用 4*sizeof(int) 字节,对于当今的大多数机器来说通常为 16 字节,您不能神奇地将其更改为 4*sizeof(double) 字节,通常为 32 字节(这将是获取内存的一个很好的技巧)免费升级...)。

没有办法在编译时更改char const __func__[] 为 a ,抱歉。wchar_t[]另一方面,您应该能够在许多需要使用 wchar_t 数组的地方使用普通char const数组__func__(数组,而不是宽字符串文字!):

std::wofstream ws; ws << __func__;
wchar_t buffer[64]; swprintf(buffer, sizeof(buffer), L"%s\n", __func__);
Run Code Online (Sandbox Code Playgroud)

问题在于函数接受 wchar_t* 而没有 char* 重载。那么您将无法在运行时转换字符串(请参阅mbstowcs)。

如果有帮助,这可能是一个如何方便地为每个函数只执行一次的想法:

template <size_t N>
struct F
{
    wchar_t name[N];
    F(char const* func)
    {
        mbstowcs(name, func, N);
    }
};
#define F_INIT static F<sizeof(__func__)> func(__func__)
#define FUNC func.name

void foo()
{
    F_INIT;
    std::wcout << FUNC;
}

int main(int argc, char* argv[])
{
    F_INIT;
    std::wcout << FUNC;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

给它们(模板+宏)任何最适合您的名称......

  • 另一种方法,但这样做:`static std::wstring ws_func(std::wstring_convert&lt;std::codecvt_utf8_utf16&lt;wchar_t&gt;&gt;().from_bytes(__func__));` 作为静态,它仅被构造一次。该转换器仅在 wstring 的构造函数中使用,因此也仅构造一次。这样就不需要模板或普通结构。 (2认同)
  • @BenKey,虽然 `_T(__FUNCTION_)` 工作正常(`__FUNCTION__` 是 MSVC 特定的),但相同的方法不适用于 `__func__` (2认同)