可以以嵌套方式使用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>)'|

最佳答案

您走的路正确,但是错过了几件事。


对于二进制操作,std::transform仅采用第一个输入范围的开始和结束迭代器;它需要第二个范围的开始迭代器,并假定第二个范围至少与第一个范围一样大(这样,对于[first1, last1)范围内的任何元素,在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;
    }
);


实际上,如果需要签名,我们可以注释掉第二个transform()调用。

在操作here中查看它。

经过编辑以提高通用性,无论数据的实际类型如何,都可以随便插入。

关于c++ - 3D vector -转换和减号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57594645/

10-11 17:03