gpt4 book ai didi

c++ - 有没有优雅的方式在多态 lambda 中编写类型别名

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:04 27 4
gpt4 key购买 nike

考虑以下代码:

#include <initializer_list>
#include <vector>

auto cref_lambda = [] (const auto& il){
using T= typename decltype(il)::value_type;
};

auto cval_lambda = [] (const auto il){
using T=typename decltype(il)::value_type;
};

int main(){
std::initializer_list<int> il;
cref_lambda(il);
cval_lambda(il);
}

cref_lambda 无法编译,因为我们试图将::转化为引用。

我知道解决方法(使用 std::remove_reference_t 或仅使用 decltype(*il.begin());)但我想知道是否有在这里使用更好的成语。

最佳答案

解决手头问题的方法是添加 std::decay_tdecltype操作说明。来自 cppreference :

Applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit conversions to the type T, removes cv-qualifiers, and defines the resulting type as the member typedef type.

最重要的是,它充当不符合上述任何注解的类型的标识。因此写是安全的

using T = typename std::decay_t<decltype(il)>::value_type;   

获取不合格value_type , 独立于函数签名。


现在到你问题的另一部分,如何写得更短。好吧,就您的示例而言,可以说,由于您的 lambda 不捕获任何内容,因此也可以用免费的函数模板替换它。

template < typename T >
void cref(std::initializer_list<T> const &il) {
/* use T and il */
}

或者它是否适用于任何容器

template < typename U >
void cref(U const &il) {
using T = typename U::value_type;
/* use T and il */
}

第一种情况的明显优势是,您可以访问 T = value_type “免费”。另一个优点(在我看来)是如果你不小心用不是 std::initializer_list<T> 的东西调用这个函数,你会得到一个更清晰的编译器错误。 .您可以通过添加 static_assert 来弥补 lambda 的这个缺点。但这会进一步拉紧您最初想要找到的“短缺”。


最后,如果您真的喜欢 lambda 风格的函数编写方式,或者您必须捕获一些东西并且不能使用自由函数方法,您可能需要考虑使用模板 lambda 的 GCC 扩展:

auto cref_lambda = [] <typename U> (U const &il){
using T = typename U::value_type;
};

这可能是您可以获得的最短时间。

关于c++ - 有没有优雅的方式在多态 lambda 中编写类型别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50126256/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com