我正在创建一个包含以下部分的记录器:
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
Run Code Online (Sandbox Code Playgroud)
有了这样的想法:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
Run Code Online (Sandbox Code Playgroud)
这一切都按预期工作,但当我这样做时:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
Run Code Online (Sandbox Code Playgroud)
这是行不通的:
void log(const ostream& os)
{
std::streambuf* buf = os.rdbuf();
if( buf && typeid(*buf) == typeid(std::stringbuf) )
{
const std::string& format = dynamic_cast<std::stringbuf&>(*buf).str();
cout << format << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
导致'format'包含垃圾数据而不是通常正确的字符串.
我认为这是因为<<运算符返回的临时ostream比它来自的字符串流更长.
还是我错了?
(为什么string()以这种方式工作?是因为它返回对它自己的引用吗?我假设是的.)
我真的很想这样做,因为我在登录发布模式时会省去额外的分配.
任何以这种方式完成任务的指针或技巧都会受到欢迎.在我的实际解决方案中,我有许多不同的日志功能,它们都比这更复杂.所以我更希望在调用代码中以某种方式实现它.(如果可能的话,不要修改我的#define) …
我创建了一个包含以下代码段的新项目:
char* strange = "(Strange??)";
cout << strange << endl;
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
(奇怪]
因此翻译'??)' - >']'
调试它显示我的char*字符串文字实际上是该值,它不是流转换.这显然不是我见过的元字符序列.某种Unicode或宽字符序列也许?我不这么认为......我试过禁用所有相关的项目设置无济于事.
有人有解释吗?
以下部分演示了我的问题:( GCC上的编译错误)
stringstream ss;
string s;
ss << "Hello";
// This fails:
// s.swap(ss.str());
// This works:
ss.str().swap(s);
Run Code Online (Sandbox Code Playgroud)
我的错误:
constSwap.cc:14: error: no matching function for call to 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
basic_string.tcc:496: note: candidates are: void std::basic_string<_CharT, _Traits, _Alloc>::swap(std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
Run Code Online (Sandbox Code Playgroud)
虽然我理解stringstream中的str()返回一个临时的,但它没有意义,并且我不应该立即明白我应该使用局部变量作为参数而不是我的第一直觉调用临时交换.
显然,直接赋值工作得更好,而较新的C++标准已经移动了完美的语义,但这些并不适用于我的实现.
Visual Studio因为放松了C++标准而没有出现这个问题.我有点已经理解了对临时事物的整个const引用(我假设是我编译错误的原因).
我的问题:任何人都可以向我解释这是否是唯一的解决方案,并且可能会向我解释将来如何考虑这个问题,以便我可以发现并解决类似的问题?
(如果没有人有任何有用的见解,我至少会在这里为有类似问题的人发帖)
c++ ×3
temporary ×2
c ×1
iostream ×1
stl ×1
stream ×1
string ×1
stringstream ×1
trigraphs ×1
visual-c++ ×1