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

标签 c++ type-alias

考虑以下代码:

#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/

相关文章:

c++ - 搜索可以像 map 一样工作并检索其他信息的数据结构

c++ - 变量未初始化为条件 c++

string - Go 中别名类型之间的转换会创建副本吗?

swift - 如何在 Swift 中将结构声明为 typealias 的返回类型

c++ - 给定一个任意容器,推导出一个相关类型的容器类型

scala - 我如何将Either 推广到更多(和递归)类型?

c++ - Roslyn 是否支持 C++ 生成语法树

c++ - 应用程序退出时出现 SegFault

c++ - 在 MS VC 2013 Express 中将 C++ dll 从 32 位转换为 64 位

c++ - "using"类作用域的类型别名 : [when] can usages in methods PRECEDE the type alias?