【问题标题】:problem with function template parameter pack函数模板参数包的问题
【发布时间】:2019-05-30 17:12:13
【问题描述】:

为什么下面的编译失败?

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

区别在于字符的书写顺序。我可以很容易地解决这个问题,但我很想知道我的第一个示例违反了什么规则。

【问题讨论】:

    标签: c++ c++11 templates


    【解决方案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 来回包”?你是不是最后一个 int 部分?

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

    【讨论】:

    • 我不确定我是否理解,在我的示例中,模板参数包没有以下参数(即,您引用的示例中没有与 typename U 等效的参数)。
    • 好吧,我尝试用double last 替换int last,但没有任何区别。暂时忘记 C++ 并没有歧义,显然给定两个实际参数,参数包使用第一个参数,而普通参数是第二个,这是唯一适合的。我仍然不确定 C++ 的哪些规则意味着这在实践中不起作用。
    • 好的,我想知道我是否最终没有得到你的问题;你的问题是关于 init_output_string(prev...); 不使用第一个参数调用函数的问题吗?如果是这样,请记住在这种情况下完整的函数名称是 init_output_string,因此它不匹配任何原型...
    • 我越来越糊涂了。如果第一个示例中的init_output_string(prev...); 与任何原型都不匹配(我也不理解),为什么第二个示例中的init_output_string(rest...); 会编译?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    相关资源
    最近更新 更多