功能模板参数包出现问题

时间:2019-05-30 08:17:37

标签: c++ c++11 templates

为什么以下内容无法编译?

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);

不同之处在于字符的写入顺序。我可以很容易地解决这个问题,但是我很好奇知道我的第一个示例违反了什么规则。

1 个答案:

答案 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组件是不是?

想象一下,编译器只是遍历参数列表,应该直接知道在哪里停止打包。