我有一个理想情况下应如下所示的函数:
\ntemplate<typename... t_buffers, t_function function>\nvoid iterate_buffers(t_buffers &&... buffers, t_function &&function);\nRun Code Online (Sandbox Code Playgroud)\n但是,除非参数包类型位于最后,否则无法推断出参数包类型,因此我的函数签名如下:
\ntemplate<typename... t_buffers_and_function>\nvoid iterate_bufferes(t_buffers_and_function &&... buffers_and_function);\nRun Code Online (Sandbox Code Playgroud)\n然后参数会被重新排列,以便函数排在第一位。为了执行此改组,我使用了此处描述的技术,但在尝试转发元组时遇到了问题。
\n这是一个存在问题的简化示例:
\ntemplate<typename... t_args>\nvoid inner(std::tuple<t_args &&...> args) {};\n\ntemplate<typename... t_args>\nvoid outer(t_args &&... args) {\n inner(std::forward_as_tuple(std::forward<t_args>(args)...));\n}\nRun Code Online (Sandbox Code Playgroud)\n如果我传递右值(例如通过调用outer(1, 2);),它会按预期工作。但是,如果我传递左值 ( int x = 1; int y = 2; outer(x, y);),则会出现以下语法错误:
error: could not convert \xe2\x80\x98std::forward_as_tuple(_Elements&& ...) [with _Elements = {int&, int&}]((* & std::forward<int&>((* & args#1))))\xe2\x80\x99 from \xe2\x80\x98std::tuple<int&, int&>\xe2\x80\x99 to \xe2\x80\x98std::tuple<int&&, int&&>\xe2\x80\x99\ninner(std::forward_as_tuple(std::forward<t_args>(args)...));\n~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nRun Code Online (Sandbox Code Playgroud)\n因此forward_as_tuple …
c++ tuples variadic-templates perfect-forwarding forwarding-reference
请考虑以下代码:
#include <iostream>
#include <tuple>
#include <utility>
// A.
template <typename... Args>
void f (const char* msg, Args&&... args)
{
std::cout << "A. " << msg << "\n";
}
// B.
template <typename... Args>
void f (const char* msg, std::tuple<Args...>&& t)
{
std::cout << "B. " << msg << "\n";
}
struct boo
{
const std::tuple<int, int, long> g () const
{
return std::make_tuple(2, 4, 12345);
}
};
int main ()
{
f("First", 2, 5, 12345);
f("Second", std::make_tuple(2, 5, 12345)); …Run Code Online (Sandbox Code Playgroud)