为什么以下内容无法编译?
inline Obj init_output_string() { return open_output_string(); }
template<typename... Args>
Obj init_output_string(Args... prev, int last)
{
Obj port(init_output_string(prev...));
write_char(port, last);
return port;
}
int ch1 = ...;
int ch2 = ...;
Obj port = init_output_string(ch1, ch2);
(对于MSVC,错误是'init_output_string': no overloaded function takes 2 arguments
,g ++给出了类似的错误)。
但是以下变体确实可以编译
inline Obj init_output_string() { return open_output_string(); }
template<typename... Args>
Obj init_output_string(int first, Args... rest)
{
Obj port(init_output_string(rest...));
write_char(port, first);
return port;
}
int ch1 = ...;
int ch2 = ...;
Obj port = init_output_string(ch1, ch2);
不同之处在于字符的写入顺序。我可以很容易地解决这个问题,但是我很好奇知道我的第一个示例违反了什么规则。
答案 0 :(得分:1)
您的构造不正确。 参见https://en.cppreference.com/w/cpp/language/parameter_pack
在功能模板中,模板参数包可能较早出现 在列表中假设可以从中推导出以下所有参数 函数参数,或具有默认参数:
给出的示例是(在您的情况下为后者):
template<typename... Ts, typename U>
struct Invalid; // Error: Ts.. not at the end
template<typename ...Ts, typename U, typename=void>
void valid(U, Ts...); // OK: can deduce U
// void valid(Ts..., U);
// Can't be used: Ts... is a non-deduced context in this position
问题是“如何推断从包装袋中取出情报的位置”?您最后一个int组件是不是?
想象一下,编译器只是遍历参数列表,应该直接知道在哪里停止打包。