gpt4 book ai didi

c++ - 当当前字符串的长度与前一个字符串的长度相同时,为什么我的字符串连接器发出前一个字符串而不是当前字符串

转载 作者:行者123 更新时间:2023-11-30 02:37:08 24 4
gpt4 key购买 nike

所以,我有以下奇特的字符串连接器:

#include <iostream>
#include <sstream>

class Internal final
{
~Internal() = delete;
static std::stringstream stream;
static const std::ios_base::fmtflags defflags;
template <typename T, typename ...P> struct Append
{
static void func(const void *const *p)
{
stream << *(T *)*p;
Append<P...>::func(p + 1);
}
};
template <typename T> struct Append<T>
{
static void func(const void *const *p)
{
stream << *(T *)*p;
}
};
template <typename ...P> friend const char *Jo(const P &... p);
};

std::stringstream Internal::stream;
const std::ios_base::fmtflags Internal::defflags = stream.flags();

template <typename ...P> const char *Jo(const P &... p) // 'Join', returned pointer is valid until next call
{
Internal::stream.clear();
Internal::stream.flags(Internal::defflags);
Internal::stream.str("");
const void *const arr[sizeof...(P)] {&p...};
Internal::Append<P...>::func(arr);
static std::string ret = Internal::stream.str();
return ret.c_str();
}


int main()
{
// Test case:
std::cout << Jo("Hello",',',' ',"world!!", 1); // Prints `Hello, world!!1`
return 0;
}

如您所见,Jo(...) 连接所有传递的对象并返回指向结果字符串的指针。这些对象可以具有 stringstream 接受的所有类型。此外,此函数接受流操纵器并在每次调用时重置内部 stringsteram 标志。

它工作正常,但我有一个非常奇怪的问题。

考虑以下代码:

std::cout << Jo('1','2');
std::cout << Jo('3','4');

我希望它打印 1234,但它打印 1212

当我连续多次使用我的函数时,当每个结果字符串具有相同的长度时,总是会发生同样的情况。在这些情况下,它总是打印序列中的第一个字符串。

See it live.

有谁知道为什么会这样?

附言这个问题与 std::cout 优化无关,我也在没有 std::cout 的情况下进行了测试。

最佳答案

static std::string ret = Internal::stream.str();

... 只执行一次,因为它是 static 变量的初始化程序。只需删除它并从 Internal::stream.str() 返回一个 std::string

如果您想获得灵感,这里有一个 Jo 版本。我保留了静态 stringstream,但让它对 Jo 的所有实例化都是通用的,但我不确定共享它是否有意义(thread-安全问题等)。我会把旗帜留给你摆弄;)

namespace Jo_detail {
std::stringstream stream;
}

template <class... Args>
std::string Jo(Args &&... args) {

Jo_detail::stream.str("");

// Classic expander trick with dummy array
using ex = int[];
(void) ex { 0, (void(Jo_detail::stream << std::forward<Args>(args)), 0)... };

// str() returns a copy anyway
return Jo_detail::stream.str();
}

关于c++ - 当当前字符串的长度与前一个字符串的长度相同时,为什么我的字符串连接器发出前一个字符串而不是当前字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31971641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com