模板仿函数和class模板参数推导

Template functor and class template parameter deduction

我正在尝试实现一个 class,它是跨链表的迭代器。我想对其进行模板化,以便您可以使用仿函数构造它以确定我们何时迭代到最后,但我无法通过 class 构造函数模板推导来推断仿函数的类型。

我正在尝试做的简化示例:

#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 吗?我是不是做错了什么?

要使 CTAD 正常工作,您不能提供任何模板参数,并且由于无法推导 T,您还需要提供第二个模板参数(即没有 CTAD)。

示例:

auto l = [b]() -> bool { return false; };
C<B,decltype(l)> foo(&b, std::move(l));

不过您可以添加辅助函数模板:

template<typename T, typename F>
auto C_creator(A* a, F&& f) { return C<T,F>(a, std::forward<F>(f)); }

auto foo = C_creator<B>(&b, [b]() -> bool { return false; });

或者更改构造函数以采用 T* 而不是 A* 以便可以推导出 T

C(T* a, F&& f) : a_(a), f_(std::move(f)) {}

auto foo = C(&b, [b]() -> bool { return false; });