0

Why the commented lines of the following does not compile? Can I use std::transform with async? For testing it is hard coded. Finally, I want to to use it for millions of points.

#include <algorithm>
#include <future>
#include <iostream>
#include <vector>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

namespace bg = boost::geometry;

typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t; 

void CreatePolygon(polygon_t &poly)
{
  polygon_t polygon2{ {{0.0, 0.0}, {0.0, 5.0}, {5.0, 5.0}, {5.0, 0.0}, {0.0, 0.0}},
                       {{1.0, 1.0}, {4.0, 1.0}, {4.0, 4.0}, {1.0, 4.0}, {1.0, 1.0}} }; 
  poly = polygon2;

}

void PointsInPolygonMultiThreaded1()
{
  polygon_t poly;
  CreatePolygon(poly);

  point_t p1(.5, .5), p2(2.0, 2.0), p3(3.0, 3.0), p4(4.5, 4.5);

  std::vector<point_t>  p_vec1({ p1, p2 });
  std::vector<point_t>  p_vec2({ p3, p4 });

  std::vector<bool> vec_b1(p_vec1.size());
  std::vector<bool>::iterator it;
  //std::async(std::transform, begin(p_vec1), end(p_vec1), begin(vec_b1), [poly](point_t& x) {return boost::geometry::within(x, poly); });

  std::vector<bool> vec_b2(p_vec1.size());
  //std::async(std::transform, begin(p_vec2), end(p_vec2), begin(vec_b2), [poly](point_t& x) {return boost::geometry::within(x, poly); });

  std::vector<bool> final_result(begin(vec_b1), end(vec_b1));
  final_result.insert(end(final_result), begin(vec_b2), end(vec_b2));
}
qqqqq
  • 837
  • 12
  • 31

1 Answers1

0

Because std::transform is a template function the compiler has to try to deduce the template parameters when instantiating the function, however, this deduction is failing. The compile then moves on to attempt to use other overloads of std::async in an attempt to find a suitable alternative, which when it cannot results in the final compile error.

This can be resolved by providing the compiler with enough information to work out template parameters it is failing to deduce. Once such way of doing this is as follows:

#include <algorithm>
#include <future>
#include <iostream>
#include <vector>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

namespace bg = boost::geometry;

typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
typedef bg::model::polygon<point_t> polygon_t; 

void CreatePolygon(polygon_t &poly)
{
  polygon_t polygon2{ {{0.0, 0.0}, {0.0, 5.0}, {5.0, 5.0}, {5.0, 0.0}, {0.0, 0.0}},
                       {{1.0, 1.0}, {4.0, 1.0}, {4.0, 4.0}, {1.0, 4.0}, {1.0, 1.0}} }; 
  poly = polygon2;

}

void PointsInPolygonMultiThreaded1()
{
  polygon_t poly;
  CreatePolygon(poly);

  point_t p1(.5, .5), p2(2.0, 2.0), p3(3.0, 3.0), p4(4.5, 4.5);

  std::vector<point_t>  p_vec1({ p1, p2 });
  std::vector<point_t>  p_vec2({ p3, p4 });

  std::vector<bool> vec_b1(p_vec1.size());
  std::vector<bool>::iterator it;

  using InputItType = std::vector<point_t>::iterator;
  using OutputItType = std::vector<bool>::iterator;
  auto const unaryOp = [poly](point_t& x) {return boost::geometry::within(x, poly); };
  using UnaryType = decltype(unaryOp);

  // Provide the missing type information the compiler fails to deduce.
  std::async(std::transform<InputItType, OutputItType, UnaryType>, begin(p_vec1), end(p_vec1), begin(vec_b1), unaryOp);

  std::vector<bool> vec_b2(p_vec1.size());
  std::async(std::transform<InputItType, OutputItType, UnaryType>, begin(p_vec2), end(p_vec2), begin(vec_b2), unaryOp);

  std::vector<bool> final_result(begin(vec_b1), end(vec_b1));
  final_result.insert(end(final_result), begin(vec_b2), end(vec_b2));
}
Antony Peacock
  • 449
  • 4
  • 8