3D向量-转换和减号

时间:2019-08-21 15:12:46

标签: c++ stl

std :: transform可以嵌套使用吗?尝试这样做:

                    {
                        return std::transform(asciivec(inner.front()).begin(), asciivec(inner.front()).end(), asciivec(inner.back()).begin(), asciivec(inner.back()).end(),out.begin(), std::minus<float>{});
                    }
                   );
Error: 
stl_algo.h||In instantiation of '_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = __gnu_cxx::__normal_iterator<const std::vector<std::__cxx11::basic_string<char> >*, std::vector<std::vector<std::__cxx11::basic_string<char> > > >; _OIter = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; _UnaryOperation = main()::<lambda(const auto:1&)>]':|


error: no matching function for call to 'transform(std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, std::minus<float>)'|

1 个答案:

答案 0 :(得分:1)

您步入正轨,但错过了几件事。

  • 对于二进制操作,std::transform仅采用第一个输入范围的开始和结束迭代器;它需要第二个范围的开始迭代器,并假设第二个范围至少与第一个范围一样大(因此,对于[first1, last1)范围内的任何元素,在{{1 }}。

  • 假设first2返回一个临时对象(而不是对缓存对象的引用),则迭代器asciivec()asciivec(inner.front()).begin()实际上将引用两个不同的范围。这将导致运行时错误。您需要将asciivec(inner.front()).end()调用的结果缓存在lambda内部,以赋予它们足够的持久性以完成操作。

  • asciivec()将其操作数评估为std::minus,因此将为lhs - rhs返回-1。由于您的示例结果是肯定的,因此我假设您需要绝对值,并因此扩展并注释了我的代码。

因此,考虑到这一点,我们可以进行一些细微改动...

std::minus<float>{}('a', 'b')

如果实际上需要签名,我们可以注释掉第二个// Renamed "inner" to "in" for convenience here. std::transform (inp.cbegin(), inp.cend(), out.begin(), [&](const auto& in) { // Tying element type to asciivec() for convenience. using Container = decltype(asciivec(in.front())); using Elem = typename Container::value_type; //using Elem = typename decltype(asciivec(in.front()))::value_type; // Create non-temporary vectors first, to guarantee expected results. std::vector<Container> inner = { asciivec(in.front()), asciivec(in.back()) }; // Use either... // static Container ret; // ret.clear(); ret.resize(inner.front().size()); // Or... Container ret(inner.front().size()); std::transform(inner.front().begin(), // InputIt first1 inner.front().end(), // InputIt last1 inner.back().begin(), // InputIt first2 //asciivec(inner.back()).end(), // Omit ret.begin(), // OutputIt d_first std::minus<float>{}); // BinaryOperation binary_op // I'm positive you want absolute values. ;3 // Lambda provides nice, clean overload resolution, compared to a function pointer or similar. std::transform(ret.begin(), ret.end(), ret.begin(), [=](const Elem& e) { return std::fabs(e); }); return ret; } ); 调用。

查看实际情况here

经过编辑以增加通用性,不管数据的实际类型是什么,都可以插入。