lambda 的 C++ 模板类型推断

标签 c++ templates lambda

假设我有这个功能:

template <typename T>
T sum(std::vector<T> const& v) {
    T acc = T();
    for (auto const& e : v) {
        acc += e;
    }
    return acc;
}

这里C++只允许用vector调用这个函数,可以自动推断出T类型参数。

有什么方法可以使用 lambda 来做同样的事情吗?我知道它们在语义上与仿函数相同,我可以在那里轻松地做到这一点,但我对内联 lambda 很感兴趣。我知道我可以做到这一点:

[](auto& v) { ... }

但这匹配任何东西,甚至是非 vector 参数(即使正文导致编译器错误)。

最佳答案

在 C++20 中,我们可以在捕获列表之后指定模板参数:

auto accum = []<class T>(std::vector<T>& v) {
    auto acc = T{};
    for (auto const& e : v) {
        acc += e;
    }
    return acc;
};

Demo

在此期间,假设您现在一直依赖类型特征来推断 value_type:

auto accum = [](auto& v) {
    auto acc = typename std::decay_t<decltype(v)>::value_type{};
    for (auto const& e : v) {
        acc += e;
    }
    return acc;
};

如果你想强制执行特定的容器,你可以使用 static_assert:

auto accum = [](auto& v) {
    using ttype = std::decay_t<decltype(v)>;
    using vtype = typename ttype::value_type;
    static_assert(std::is_same_v<std::vector<vtype>, ttype>);
    auto acc = vtype{};

    for (auto const& e : v) {
        acc += e;
    }
    return acc;
};

例如:

int main(){

    std::vector<int> v{1,2,3};
    std::list<double> l{4.0,5.0,6.0};
    auto accum = [](auto& v) {
        auto acc = typename std::decay_t<decltype(v)>::value_type{};
        for (auto const& e : v) {
            acc += e;
        }
        return acc;
    };

    std::cout << accum(v) << std::endl;
    std::cout << accum(l) << std::endl;
}

Demo for any iterable container with a value_type

Demo with static_assert for vector type


因为你提到你没有使用 STL 容器,而是 Phantom Types , 那么你有两个选择:

  • 像这样使用 value_type = PHANTOM_TYPE 将 typedef 添加到您的强类型枚举中
  • 创建一个单独的特征类来推断value_type:

    模板 结构体 { 民众: SUInt(无符号整数值):m_value(值){} 内联 unsigned int& Value () { return m_value; } 私有(private)的: 无符号整数 m_value; };

    模板 结构 SUInt_traits{};

    模板 结构 SUInt_traits>{ 使用 value_type = T; };

然后您可以在您的 lambda 中使用它 like so :

auto do_a_thing = [](auto& v) {
    auto acc =  typename SUInt_traits<std::decay_t<decltype(v)>>::value_type{};
    // ...
};

关于lambda 的 C++ 模板类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48117477/

相关文章:

jQuery 幻灯片在自定义 Wordpress 模板中的一张图片后停止

java - Java 中的这段递归 lambda 调用是如何工作的

c++ - -whole-library 不可用时的解决方法

C++封装,有什么用

C++ 将 std::initializer_list 强制为模板函数中的容器

c++ - 在 lambda 中访问循环控制变量

c++ - 通过引用识别 Lambda

c++ - SQL numeric(18,0) 数据类型对应的 C++ 数据类型是什么?

c++ - 显式初始化成员是什么意思?

c++ - std::thread 构造函数第三个模板参数的目的是什么?