这个令人遗憾的冗长示例是我正在尝试编写的一段真实代码的精简版。它有两个问题。首先,正如所写,它不能编译:错误是
error: cannot bind ‘std::string’ lvalue to ‘std::string&&’
error: initializing argument 3 of ‘void pack_arg(datum*, size_t, std::string&&)’
并且由对 的调用触发shut_the_door
。&&
如果我在 的相关重载中取出pack_arg
,那么它会编译,但生成的代码似乎不必要地复制了两个字符串。其次,我需要确保数组d
持有指针的所有临时字符串在调用vprocess
. 现在,生成的代码似乎在调用之前就破坏了它们。
只要我有机会process
通过可重载的函数调用运行每个参数,我愿意考虑对数组的填充方式进行相当彻底的更改,而独立于所有其他此类参数。(特别是,我怀疑如果我可以在联合中使用临时初始化引用的特殊规则会使问题 2 消失std::string&
,但由于datum
数组的每个成员都是通过赋值而不是初始化填充的,所以目前不会工作,我不知道如何通过初始化填充它而不会丢失对 的调用pack_arg
,这在更大的上下文中是必要的。)
编辑:使用std::forward
between pack_args
andpack_arg
似乎没有帮助;我得到完全相同的错误消息。
#include <string>
#include <stddef.h>
using std::string;
union datum
{
const string* s;
int i;
};
inline void
pack_arg(datum* d, size_t n, int t)
{
d[n].i = t;
}
inline void
pack_arg(datum* d, size_t n, string && t)
{
d[n].s = &t;
}
inline void
pack_args(datum*, size_t)
{
}
template <typename X, typename... XS> inline void
pack_args(datum* d, ::size_t n, X&& x, XS&&... xs)
{
pack_arg(d, n, x);
pack_args(d, n+1, xs...);
}
extern void vprocess(datum*, size_t);
template <typename... XS> inline void
process(XS&&... xs)
{
size_t n = sizeof...(xs);
datum d[n];
pack_args(d, 0, xs...);
vprocess(d, n);
}
extern string shut_the_door();
void
demo()
{
process(1, 2, "buckle my shoe", 3, 4, shut_the_door());
}