【问题标题】:std::to_string is not declared compile error in aix在 aix 中未声明 std::to_string 编译错误
【发布时间】:2015-02-15 15:08:34
【问题描述】:

我正在 AIX 环境中编译我的代码。它给了我错误“std::to_string”未声明 在 Windows 中成功编译了相同的代码。

define LOG_MSG(message) CLogManager::LogMessage(CLogManager::CurrentDateTime() + " - " + std::string(__FILE__) + "[" + std::to_string(static_cast<_ULonglong>(__LINE__)) + "] : " + std::string(message) + "\n")

这是宏,我将其用作

LOG_MSG(" ** BEGIN StorePasswordFromFile()");

此宏用于记录目的

【问题讨论】:

  • #include&lt;string&gt;了吗?
  • 你的编译器支持 C++11 吗?
  • 您使用的是 IBM XLC 还是 GCC?
  • 我正在使用 IBM XLC... 也包含字符串

标签: c++ linux c++11 aix


【解决方案1】:

我不确定最新的xlC 14.1(或您使用的任何版本)对std::to_string() 有多少支持。

如果支持不完整,C 有一个可怕的双宏方法 (a)__LINE__ 转换为 C 字符串,这样你就可以使用std::string,和你一样对于 __FILE__message 项目,C++ 预处理器似乎一直忠于其可怕的根源:-)

代码:

#include <stdio.h>
#define STR1(x) # x
#define STR2(x) STR1(x)
int main(void) {
    char x[] = __FILE__;
    char y[] = STR2(__LINE__);
    printf("file = %s, line = %s\n",x,y);
    return 0;
}

输出:

file = qq.c, line = 6

显示__LINE__ 已成功变形为 C 字符串值。

您应该可以在宏中使用类似的方法:

#define STR1(x) # x
#define STR2(x) STR1(x)
#define LOG_MSG(message) CLogManager::LogMessage( \
    CLogManager::CurrentDateTime() + " - " + \
    std::string(__FILE__) + "[" + \
    std::string(STR2(__LINE__)) + "] : " + \
    std::string(message) + "\n")

int main() {
    LOG_MSG ("My hovercraft is full of eels");
    return 0;
}

使用g++ -E qq.cpp 进行预处理为您提供:

  CLogManager::LogMessage( CLogManager::CurrentDateTime() + " - " + std::string("qq.cpp") + "[" + std::string("10") + "] : " + std::string("My hovercraft is full of eels") + "\n");

(仅显示相关行)似乎与您想要的匹配。

不过,附带说明一下,由于您似乎可以添加像 "[" 这样的 C 字符串 而无需 需要显式构造字符串,我不确定您是否需要 em> std::string() 完全为那些打电话。您仍然需要 C 宏 hack 将整数转换为 C 字符串,但是一旦完成,您应该可以按原样使用它。

将最终宏更改为:

#define LOG_MSG(message) CLogManager::LogMessage( \
    CLogManager::CurrentDateTime() + " - " + \
    __FILE__ + "[" + \
    STR2(__LINE__) + "] : " + \
    message + "\n")

会给你:

CLogManager::LogMessage( CLogManager::CurrentDateTime() + " - " + "qq.cpp" + "[" + "10" + "] : " + "My hovercraft is full of eels" + "\n");

这是否是一个好主意我会留给更广泛的社区,但它至少可以解决你的直接问题。我可能会将全部内容放在 #if/#else/#endif 中,以便了解 std::to_string() 的 C++11 编译器可以使用更被接受的方法。


(a)如果你对为什么感兴趣,我会在下面解释。

根据C11 6.10.3.4 /1### 宏运算符实际上优先于宏替换的递归性质:

在替换列表中的所有参数都被替换并且#和##之后 处理已经发生,所有地标预处理标记都将被删除。这 然后重新扫描生成的预处理令牌序列,以及所有后续 预处理源文件的标记,用于替换更多的宏名称。

也就是说代码:

#define STR(x) # x
STR(__LINE__)

实际上会导致"__LINE__",因为#首先发生,一旦发生,字符串文字中的__LINE__不会被进一步替换。通过执行两步过程:

#define STR1(x) # x
#define STR2(x) STR1(x)
STR2(__LINE__)

第一级替换将STR2(__LINE__) 变成STR1(3),因为__LINE__ 本身可以扩展。

然后第二级将STR1(3),通过# 3,变成"3"

也许以下可能会有所帮助:

#define STR1(x) # x
#define STR2a(x) STRn(x)
#define STR2b(x) STR1(x)

STR1(__LINE__)
STR2a(__LINE__)
STR2b(__LINE__)

注释后的输出是:

"__LINE__"  - stringise, no further processing of __LINE__ inside literal.
STRn(6)     - shows first stage of replacement, line number replacement.
"7"         - shows full process.

【讨论】:

  • 嗨,感谢您的解决方案,它对我有用.. 但您能告诉我它是如何工作的吗?
  • @user2991556:请参阅答案的附录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2018-03-26
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
相关资源
最近更新 更多