问题描述
关于上一个问题(是否可以通过引用从lambda返回类型T的对象而无需使用尾随返回类型语法?),我想知道是否还有其他重要案例或示例,其中使用lambda时 trailing-return-type 语法是否可以不能被避免.
In relation to a previous question (Is it possible to return an object of type T by reference from a lambda without using trailing return type syntax?), I was wondering if there is any other significant case or example in which trailing-return-type syntax, when using lambdas, can not be avoided.
推荐答案
在C ++ 14中,一个人为设计的示例是将sfinae与通用lambda结合使用:
In C++14, a bit contrived example is the use of sfinae in combination with a generic lambda:
[](auto &&arg)
-> decltype(arg.f(), void())
{ /* do whatever you want */ }
无论如何,有人可能会说static_assert
就足够了:
Anyway one could argue that a static_assert
suffices:
[](auto &&arg) {
static_assert(has_metod_f<std::decay_t<decltype(arg)>>::value, "!");
/* do whatever you want */
}
has_method_f
是常见的检测器习惯用法.
无论如何,想象一下您想从一堆lambda开始构造组合函子的情况:
Where has_method_f
is the common detector idiom.
Anyway, imagine a case where you want to construct a composed functor starting from a bunch of lambdas:
#include<utility>
#include<iostream>
template<typename...>
struct Base;
template<typename Func, typename... Others>
struct Base<Func, Others...>: Func, Base<Others...> {
Base(Func func, Others... others)
: Func{std::move(func)}, Base<Others...>{std::move(others)...}
{}
template<typename... Args>
auto operator()(int, Args&&... args)
-> decltype(Func::operator()(std::forward<Args>(args)...)) {
Func::operator()(std::forward<Args>(args)...);
}
template<typename... Args>
auto operator()(char, Args&&... args) {
Base<Others...>::operator()(0, std::forward<Args>(args)...);
}
};
template<>
struct Base<> {
template<typename... Args>
auto operator()(Args&&...) {
std::cout << "fallback" << std::endl;
}
};
template<typename... Ops>
struct Mixin: Base<Ops...> {
Mixin(Ops... ops)
: Base<Ops...>{std::move(ops)...}
{}
template<typename... Args>
auto operator()(Args&&... args) {
return Base<Ops...>::operator()(0, std::forward<Args>(args)...);
}
};
struct T { void f() {} };
struct U {};
int main() {
auto l1 = [](auto &&arg) -> decltype(arg.f(), void()) {
std::cout << "accept T" << std::endl;
};
auto l2 = [](U) {
std::cout << "accept U" << std::endl;
};
Mixin<decltype(l1), decltype(l2)> mixin{std::move(l1), std::move(l2)};
mixin(T{});
mixin(U{});
mixin(0);
}
在这种情况下,static_assert
将阻止编译,这不是预期的结果.
另一方面,可以使用尾随返回类型在包装器的帮助下直接在lambda上启用sfinae.
In this case, a static_assert
would prevent the compilation and it is not the expected result.
On the other side, the trailing return type can be used to enable sfinae directly on the lambdas with the help of their wrappers.
这篇关于是否存在无法避免lambda中的尾随返回类型语法的情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!