需要在Sfinae中澄清Lambdas,Auto和SectType
Need clarification about Lambdas, auto and decltype in SFINAE
我一直在尝试通过阅读以下文章链接来了解Sfinae技巧,但在理解其中的某些部分方面遇到了麻烦。
完整代码:链接
我主要对这些代码行感到困惑。
// Check if a type has a serialize method.
auto hasSerialize = is_valid([](auto&& x)
-> decltype(x.serialize()) { });
template <class T> auto serialize(T& obj)
-> typename std::enable_if<decltype(hasSerialize(obj))::value, std::string>::type
{
return obj.serialize();
}
template <class T> auto serialize(T& obj)
-> typename std::enable_if<!decltype(hasSerialize(obj))::value, std::string>::type
{
return to_string(obj);
}
尤其是在Hasserialize Line中,并且在宣传中使用了它。谁能告诉我这里发生了什么?Hasserialize是一种方法吗?Hasserialize右侧的表达式(Lambda)是什么?评估的执行顺序是什么?自动在哈西里化中评估什么?
请帮助我理解这一点,因为我为此苦苦挣扎了一个星期,但仍然无法围绕它。如果有人能为此提供一个实践的例子。
谢谢
首先,此代码使用boost::hana::is_valid
-确保读取其文档并了解其在做什么。
Hasserialize是一种方法吗?
no,它是用lambda表达式初始初始化的变量。这是一个封闭。
Hasserialize右侧的表达式(Lambda)是什么?
以下代码...
auto hasSerialize = is_valid([](auto&& x) -> decltype(x.serialize()) { });
...将创建一个函数对象,当用对象调用时,如果y.serialize()
是有效的表达式,则y
将返回std::true_type
,否则std::false_type
。示例:
struct Foo { };
struct Bar { void serialize() { } };
static_assert(!hasSerialize(std::declval<Foo>()));
static_assert(hasSerialize(std::declval<Bar>()));
这是is_valid
的简单实现:
template <typename TF>
struct validity_checker
{
template <typename... Ts>
constexpr auto operator()(Ts... ts)
{
return std::is_callable<
TF(typename decltype(ts)::type...)
>{};
}
};
template <typename TF>
constexpr auto is_valid(TF)
{
return validity_checker<TF>{};
}
它只是使用 std::is_callable
来查看带有尾随decltype
的通用lambda 是否可以使用一些特定的参数来调用。如果尾声decltype
内的表达式对于某些特定参数类型无效,则lambda无法call.
is_callable
可以使用void_t
以下以下方式以Sfinae友好的方式实现:
template <typename...>
using void_t = void;
template <typename, typename = void>
struct is_callable : std::false_type { };
template <typename TF, class... Ts>
struct is_callable<TF(Ts...),
void_t<decltype(std::declval<TF>()(std::declval<Ts>()...))>>
: std::true_type { };
相关文章:
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 如何在自定义类中启用'auto loops'?
- 为什么在C++20中对lambdas使用"std::bind_front"
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 为什么结构化绑定不使用"auto&"返回对结构成员的引用,而是返回成员本身
- 擦除许多矢量元素,同时使用'auto'
- 考虑到其他好处,关键字'auto'真的有助于简化调试C++吗?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- 推理类型如何工作"auto"和按引用调用?
- 'auto *x = new some_struct{};"是一个未初始化的变量?
- 为什么 std::gcd/lcm 返回 std::common_type_t<M, N> 而不是 auto?
- 将函数参数类型声明为 auto
- 使用constexpr + auto作为返回和参数类型的奇怪类型推导
- 为什么 const auto &p{nullptr} 在 C++17 中不起作用,而 auto *p{nullptr} 不起作用?
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 使用"auto"推断嵌套初始值设定项列表的类型
- const auto & 和 auto & if reference 对象之间的区别是 const
- 需要在Sfinae中澄清Lambdas,Auto和SectType
- 使用auto参数从lambdas返回值