模板仿函数和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; });
我正在尝试实现一个 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; });