【发布时间】:2021-02-07 19:21:28
【问题描述】:
我正在尝试实现一个类,它是跨链表的迭代器。我想将它模板化,以便您可以使用仿函数构造它以确定我们何时迭代到最后,但是我无法通过类构造函数模板推导来推断仿函数的类型。
我正在尝试做的简化示例:
#include <utility>
struct A {};
struct B : A {};
template<typename T, typename F>
struct C
{
A * a_;
F f_;
C(A * a, F && f) : a_(a), f_(std::move(f)) {}
T & operator*() { return static_cast<T &>(*a_); }
};
int main()
{
B b;
C<B> foo(&b, [b]() -> bool { return false; }); // error: wrong number of template arguments (1, should be 2)
return 0;
}
在尝试实例化对象(使用 c++17 编译)时,我总是遇到模板参数错误,奇怪的是,godbolt 也给了我这些神秘的:error: expression list treated as compound expression in initializer [-fpermissive] 和 error: cannot convert 'main()::<lambda()>' to 'int' in initialization 这没有意义,但可能只是第一个错误的后果。
不应该可以从构造函数参数中推导出函子类型F吗?我在这里做错了吗?
【问题讨论】:
-
Quoth cppreference: "类模板参数推导仅在不存在模板参数列表时执行。如果指定了模板参数列表,则不会进行推导。"这意味着您不能指定某些参数并推导出其他参数 - 您必须指定所有参数,或者不指定任何参数并推导出所有参数。
-
@IgorTandetnik 真的吗?我想只要所有推导的类型都在模板参数列表中的指定类型之后那么它应该可以工作吗?
-
它以这种方式用于函数模板参数推导,但显然不适用于类模板。对于后者,要么全有,要么全无。这在实际操作中很容易看到:
std::pair p{1, 2};编译,但std::pair<int> p{1,2};不编译。 -
该死的,谢谢你的链接......是的,它被埋在了那里的笔记里。页面的第一行似乎确实暗示了部分规范的使用:“为了实例化类模板,必须知道每个模板参数,但不是必须指定每个模板参数。”
-
我想在这种情况下我也可以让第一个模板参数也可推导出来,这很容易
标签: c++ templates c++17 template-meta-programming