C++ lambda 的模板类型推断
C++ template type inference for lambdas
假设我有这个函数:
template <typename T>
T sum(std::vector<T> const& v) {
T acc = T();
for (auto const& e : v) {
acc += e;
}
return acc;
}
这里C++只允许用向量调用这个函数,并且可以自动推断T类型参数。
有什么方法可以使用lambdas做同样的事情吗?我知道它们在语义上与函子相同,我可以很容易地在那里做到这一点,但我对内联的 lambda 感兴趣。我知道我可以这样做:
[](auto& v) { ... }
但这匹配任何内容,甚至是非矢量参数(即使主体导致编译器错误)。
在 C++20 中,我们可以在捕获列表之后指定模板参数:
auto accum = []<class T>(std::vector<T>& v) {
auto acc = T{};
for (auto const& e : v) {
acc += e;
}
return acc;
};
演示
在此期间,假设您现在只能依靠类型特征来推断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;
}
演示任何带有value_type
的可迭代容器
带有vector
类型的static_assert
演示
既然您提到您没有使用 STL 容器,而是使用幻像类型,那么您有两个选择:
- 将 typedef 添加到强类型枚举中,就像这样
using value_type = PHANTOM_TYPE
创建一个单独的特征类来推断
value_type
:模板 结构体 SUInt { 公共: SUInt (unsigned int value) : m_value(value) { } inline unsigned int& Value () { return m_value; } 私人: 无符号的 int m_value; };
模板 struct SUInt_traits{};
模板 结构SUInt_traits>{ 使用 value_type = T; };
然后,您可以从 lambda 中使用它,如下所示:
auto do_a_thing = [](auto& v) {
auto acc = typename SUInt_traits<std::decay_t<decltype(v)>>::value_type{};
// ...
};
你可以使用带有 std::accumulate 的 lambda,尽管给定一个简单的总和,实际上并不需要 lambda。
相关文章:
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在 lambda 捕获中声明的变量的类型推导
- C++ 模板类型的静态 lambda 成员的构造
- Clang 工具,用于提取给定 lambda 类型的 lambda 主体
- 如果 lambda 没有指定的类型,std::function 如何接受 lambda?
- Lambda可以用作非类型模板参数吗
- 如何确定捕获不可复制参数的 lambda 的类型?
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 运算符中的不同类型? 具有无捕获,相同的签名,lambda
- 通过参数传递 lambda(无函数类型模板)
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 如何推导lambda的返回类型
- 尽管显式声明了返回类型,但对lambda的调用是不明确的
- 是否创建具有不同返回类型的lambda
- 防止 lambda 的返回类型扣除
- 在 lambda 函数 g++-4.8 中调用继承的受保护子类型
- 在 lambda 中从引用类型捕获的值的类型,不使用通用捕获
- 我可以让返回类型自动处理具有相同签名但捕获不同内容的 lambda 吗?
- 复制分配C++相同类型的 lambda