Обеспечение итератора для первого элемента контейнера пар

Ваше явление может быть сведено к простому, хотя и загадочному примеру:

MY_OUTPUT := First line
.PHONY: foo
foo:
    @echo $(MY_OUTPUT)
    $(eval MY_OUTPUT := $(shell $(info eval-time) echo Second line))
    @echo $(MY_OUTPUT)
    $(shell read -p "Hit return:")

Вывод:

$ make foo
eval-time
Hit return:

... в ожидании нажатия клавиши [117 ]

First line
Second line

Оценка рецепта выглядит следующим образом: Выделите буфер строк, которые будут содержать командные строки окончательного рецепта без синтаксиса make. Затем пройдитесь по всем строкам рецепта, выполните весь известный синтаксис make, удалите один уровень из всех кавычек ($), выполните вещи $(eval) и запишите строки в буфер. только затем перебирают результирующий список командных строк и выдают их sh по очереди. $(info) говорит нам, что строка аргумента уже была оценена заранее, что нарушает ваш предполагаемый порядок.

9
задан David Reis 23 November 2008 в 17:35
поделиться

4 ответа

Я озирался и нашел boost::transform_iterator. Я придумал этот код. Удивление, как хорошо это работает:

#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <iterator>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>

int main() {
    typedef std::map<std::string, int>::value_type value_type;
    std::map<std::string, int> a;
    a["one"] = 1;
    a["two"] = 2;

    // returns the second element 
    boost::function<int(value_type&)> f = boost::bind(&value_type::second, _1);
    std::copy(boost::make_transform_iterator(a.begin(), f), 
              boost::make_transform_iterator(a.end(), f),
              std::ostream_iterator<int>(std::cout, " "));

}

Это печатает "1 2 " к стандартному выводу.

12
ответ дан 4 December 2019 в 13:50
поделиться

Нет никакого умного решения остроты. Ваша лучшая надежда состоит в том, чтобы записать итератор обертки. Это - на самом деле довольно каноническое решение. Вы могли бы проверить, имеет ли Повышение уже то, в чем Вы нуждаетесь. В противном случае попытайтесь записать универсальную обертку, которая может быть снова использована для других проблем.

STL содержит такую названную обертку итератора reverse_iterator. Имя подразумевает свое использование.

1
ответ дан 4 December 2019 в 13:50
поделиться

Можно разделить на подклассы, например, станд.:: вектор:: const_iterator самостоятельно, повторно реализовывая оператор* и оператор-> для возврата первой из пары. Необходимо было бы также создать собственное, начинаются () и конец () функции для возврата пользовательского итератора.

Можно также создать к классам двоичной функции и передать тех, которые к inner_product.

1
ответ дан 4 December 2019 в 13:50
поделиться

В конечном счете я думаю, что Ваша идея является способом пойти. Можно использовать Повышение, чтобы помочь Вам сделать это. Для запуска Вам была бы нужна функция, которая берет Вашу пару и возвращает первый элемент. Я думаю, что Вы могли записать такое функциональное встроенное пользование библиотекой Lambda, но для пользы удобочитаемости, я думаю, что просто записал бы простую функцию, которая делает это вместо этого. Затем передача, которые функционируют с Вашими исходными итераторами для построения a transform_iterator поскольку Ваша последовательность начинается и заканчивается.

1
ответ дан 4 December 2019 в 13:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: