首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过函数C++传递字符串值

通过函数C++传递字符串值
EN

Stack Overflow用户
提问于 2012-05-29 23:48:43
回答 5查看 3.5K关注 0票数 4

我目前有一个日志系统,它接受char*和var args,然后使用它们执行printf。这在C风格的字符串中工作得很好,但我更喜欢更简洁的字符串。目前,如果我使用std::stringstream,我必须在日志记录系统之外创建字符串流,然后对字符串流给定的字符串使用char*。它看起来像这样:

代码语言:javascript
复制
std::stringstream strStream;
strStream << "The value of x is: " << x;
logging::print( strStream.str().c_str() );

我想要的是将参数传递给函数,就像我直接在字符串流中使用它们一样。从用户的角度来看,它看起来像这样:

代码语言:javascript
复制
logging::printStream("The value of x is: " << x);

或者可能是这样的:

代码语言:javascript
复制
logging::printStream("The value of x is: ", x);

有没有办法使用日志记录,这样我就可以使用字符串流,而不必在日志系统的函数之外创建它?

这一点特别重要,因为我打算创建一个宏,以防止在发布版本中编译任何函数参数。如果我必须在宏外部创建字符串流并将其传递进来,那么宏将是无用的。从技术上讲,我可以创建一个宏来完成我在这个问题中所讨论的stringstream内容,但这是相当混乱的,因为我不会总是在这个日志记录中使用stringstreams,所以我会有一个用于标准日志记录的宏,以及一个使用stringstreams的不同的宏来调用用于标准日志记录的宏。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-05-30 00:39:45

我想出了两个黑客解决方案,但它们应该是有效的。第一种方法不使用作用域解析操作符,因此更安全。第二个使用noop int变量来伪造作用域。

代码语言:javascript
复制
#define logging_printStream(token) { std::stringstream o; o << token; logging::print(o.str().c_str()); }

namespace logging { int noop; }
#define printStream(token) noop = 0; { std::stringstream o; o << token; logging::print(o.str().c_str()); }

int main(int argc, const char** argv)
{
    int i = 1;

    // MORE SAFE
    logging_printStream(i)
    logging_printStream("is this magic? " << (i ? "yes" : "no"))

    // LESS SAFE
    logging::printStream(i)
    logging::printStream("is this magic? " << (i ? "yes" : "no"))
}

由于17.6.4.3.2,我将logging__printStream更新为logging_printStream

17.6.4.3.2全局名称global.names

某些名称和函数签名集始终保留给实现:

包含双下划线_ _或以下划线后跟大写字母(2.12)开头的

  • Each名称将保留给实现,以供任何使用。
  • 每个以下划线开头的名称都保留给实现,以用作全局命名空间中的名称。

由于3.6.1的原因,我没有使用main的声明

3.6.1主函数basic.start.main

程序应包含一个名为main的全局函数,它是程序的指定开始。独立环境中的程序是否需要定义main函数是由实现定义的。实现不应预定义main函数。此函数不应被重载。它的返回类型应为,否则其类型为implementation-defined.

票数 0
EN

Stack Overflow用户

发布于 2012-05-30 05:03:44

下面的代码可以正常工作(经过测试--将cerr的输出替换为您的日志::print):

代码语言:javascript
复制
#include<sstream>
#include<iostream>

class StringstreamLogger {
private:
    std::stringstream s;

public:
    StringstreamLogger () : s (std::ios_base::out) {
    }

    ~StringstreamLogger () {
    std::cerr << s.str () << std::endl; // logging::print (s.str ().c_str ());
    }

    std::stringstream& out () {
    return s;
    }
};

int main () {
    StringstreamLogger ().out () << "My log message";
    std::cerr << "Some later output to test for prompt logging (to ensure that logging is not delayed until the end of a block)" << std::endl;
}
票数 1
EN

Stack Overflow用户

发布于 2012-05-29 23:54:49

你可以这样写:

代码语言:javascript
复制
print(static_cast<std::ostringstream&>(std::ostringstream() << "The value of x is: " << x).str().c_str());

也许这更符合你的喜好?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10802493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档