如何将 lambda 用作模板参数,C++ 中的默认值
How to use lambda as template argument with default value in C++?
我想做一件简单的事情:
void DoUntil(auto predicate = [] { return false; });
显然这不起作用 - 我必须使用模板参数:
template <typename P>
void DoUntil(P predicate = [] { return false; });
但是这个说法也不起作用 - Clang 给出了一个错误:
错误:调用 ...
注意:候选模板被忽略:无法推断模板参数"P">
如果我确实在没有参数的情况下调用函数,编译器无法从默认参数推断类型:
int main() { DoUntil(); }
我不想以任何方式使用std::function<>
。
我的问题还有其他可能的解决方案吗?
使用函数重载而不是默认参数功能。创建一个非模板函数,该函数除了模板函数外不带任何参数:
void DoUntil() ;
template <typename P>
void DoUntil(P predicate) ;
无参数版本可以简单地调用模板版本,其中包含要用作默认谓词的 lambda:
void DoUntil() { DoUntil([] { return false; }); }
原始方法的问题在于,您尝试通过指定默认参数值来提供默认模板专用化,但不指定默认模板类型。即使不涉及 lambda,以下内容也不起作用,因为T
没有默认类型,即使t
具有默认值:
template <typename T>
void Foo(T t = 3);
需要的是使用 <typename T = int>
指定T
的默认类型。
如 WhiZTiM 的回答中所述,涉及 lambda 函数的情况的默认类型必须使用 decltype
推导。这当然是因为 lambda 具有只有编译器知道的唯一类型。
lambda 是没有默认构造函数的匿名类型(当然,如果可用,您可以使用其复制/移动构造函数(。如果你必须走lambda路,你可以做到:
namespace detail{ auto predicate = [] { return false; }; }
template <typename P = decltype(detail::predicate)>
void DoUntil(P pred = detail::predicate);
而不是试图摆弄羊草。你可以走老路:
namespace detail{
struct DefaultPredicate{ bool operator()() const { return false; } };
}
template <typename P = detail::DefaultPredicate>
void DoUntil(P predicate = P{});
或者更好的是凯尔斯特兰德回答。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何将enable-if与模板参数和参数包一起使用