我一直在 try catch std 函数 lambda 中的一些参数包参数,以便将函数保存在内存中以供将来使用。
但是,在某些情况下,如果这些捕获的参数中的任何值在捕获后被修改,则这些参数的 future 使用不会达到预期的效果。
我想在我的 std 函数中存储参数包的不可变拷贝。
此代码将作为库实现,因此用户可以使用它来保存一些文本以供将来打印。这样我们就无法管理参数包中收到的参数。此示例必须对字符串、const char *、int、float 等有效
这是一个示例代码:Code link
template <typename... Args>
void doPrint(std::ostream& out, const Args &... args)
{
using expander = int[];
(void)expander{0, (void(out << args), 0)...};
}
template<typename... Args>
void printArgs(const Args & ... args)
{
doPrint(std::cout, args...);
}
class PrintTest
{
private:
std::vector<std::function<void()>> myFunctions;
public:
template<typename... Args>
void saveText(const char * text, const Args & ... args)
{
std::function<void()> f = [this, text, args...]()
{
std::cout << text;
printArgs(args ...);
std::cout << std::endl;
};
this->myFunctions.push_back(f);
}
void printSavedTexts()
{
for(auto fun : this->myFunctions)
fun();
this->myFunctions.clear();
}
};
int main()
{
PrintTest test;
{
int four = 4;
test.saveText(" Hello world ", 1, 2, 3, std::to_string(four).c_str());
std::string a ="Just";
const char * b = " be ";
test.saveText(" Bye, Bye! ", a.c_str(), b, std::string("yourself!").c_str());
a = "?";
for(int i = 0; i <= 5; ++i)
{
std::string n = std::to_string(i);
test.saveText("", n.c_str());
}
}
test.printSavedTexts();
}
这个例子的输出是:
// Hello world 1234
// Bye, Bye! ? be yourself!
// 5
// 5
// 5
// 5
// 5
// 5
它应该是:
// Hello world 1234
// Bye, Bye! Just be yourself!
// 0
// 1
// 2
// 3
// 4
// 5
是否有更好的方法将收到的文本和参数包保存在内存中以供将来使用?而不是使用存储在 vector 中的 std 函数。
最佳答案
在 test.saveText("", n.c_str());
中,您传递的是从 n
获取的 const char*
指针code> 到 saveText
,最后由 lambda 捕获。当退出 for 循环时,n 被销毁,捕获的指针悬空。对他们的尊重导致 UB。
您可以直接使用std::string
,例如test.saveText("", n);
;即删除所有 .c_str()
。
关于c++ - 如何在 std 函数 lambda c++ 11 中正确捕获参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69174186/