返回包装为 std::function
的某个 lambda 会产生错误的结果:
#include <functional>
#include <iostream>
#include <tuple>
template <typename T>
std::function<const T&()> constant(const T& c) {
return [c]() noexcept -> const T&{ return c; };
}
template <typename T>
std::function<std::tuple<T>()> zip(const std::function<T()>& f) {
return [f]() { return std::tuple{f()}; };
}
int main() {
const auto good = [f = constant(1.0)]() { return std::tuple{f()}; };
const auto bad = zip(constant(1.0));
std::cout << "good: " << std::get<0>(good()) << std::endl;
std::cout << "bad: " << std::get<0>(bad()) << std::endl;
}
输出:
$ ./a.out
good: 1
bad: 6.95282e-310
这看起来像是未定义的行为。这是怎么回事?
最佳答案
#include <functional>
#include <type_traits>
template <typename T>
std::function<const T& ()> constant(const T& c)
{
return [c]() noexcept -> const T&
{
// the captured variable is no longer a reference type!
static_assert(std::is_same_v<decltype(c), std::remove_reference_t<const T&>>);
return c;
};
}
int main()
{
auto fn = constant(42);
auto answer = fn();
}
关于c++ - 将 lambda 包装为 std::function 会产生错误的结果(是模板参数推导的危险),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68952789/