mardi 28 mars 2017

Template deduction: porting to C++11

Following code is legal for C++14 compiler

// g++ -std=c++14 -pedantic -pthread main.cpp
// output: 1 2 3 4 5 1 1 1 
#include <algorithm>
#include <vector>
#include <functional>
#include <iterator>
#include <iostream>

int main()
{
  std::vector<int> a = { 1, 2, 3, 2, 4, 5, 1, 1, 3, 5, 1, 5 }, b = { 2, 5, 5, 3 }, c;

  std::copy_if(a.begin(), a.end(), std::back_inserter(c), 
    std::bind(std::less<>(),   // this won't work in pre-C++14
      std::bind(
        std::count<std::vector<int>::iterator, int>, 
          std::bind(static_cast<std::vector<int>::iterator (std::vector<int>::*)()>(&std::vector<int>::begin), &c), 
          std::bind(static_cast<std::vector<int>::iterator (std::vector<int>::*)()>(&std::vector<int>::end), &c), 
          std::placeholders::_1
      ),
      std::bind(
        std::minus<>(), // this won't work in pre-C++14
          std::bind(
            std::count<std::vector<int>::iterator, int>, 
              a.begin(), 
              a.end(), 
              std::placeholders::_1
          ),
          std::bind(
            std::count<std::vector<int>::iterator, int>, 
              b.begin(), 
              b.end(), 
              std::placeholders::_1
          )
      )
    )
  );

  std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
}

It is meant to create vector c from elements of vector a , excluding those that match count and value of elements in vector b. E.g. if a contains three 2 and b - two of them, only one 2 would be present in c.

a) how possible to adapt this code for C++11? Intuitive leap that less<> and minus<> parameter would be ...::difference_type didn't work, compiler messages aren't helpful either

b) current version removes last matches sequence-wise. What code would remove first matches?

Aucun commentaire:

Enregistrer un commentaire