Qute от стандарта:
25.2.3 Transform [lib.alg.transform]
Требуется:
op и binary_op не должны иметь побочных эффектов.
Побочный эффект (определение из Википедии)
В вашем случае у нас есть следующий побочный эффект:
Converter c( data );
c( some_const_value ) != c( some_const_value );
У вас нет никаких гарантий для ваших алгоритмов, но я верю, что он будет работать практически на всех реализациях stl.
Предлагаемое решение
Кажется, я знаю один способ сделать то, что вам нужно:
использовать boost :: counting_iterator - для итерации по двум контейнерам;
это будет выглядеть так:
bool bit_enabled( size_t data, unsigned char number )
{
return ( data & 1 << number ) != 0;
}
std::string select_word(
const std::string& word,
size_t data,
size_t number )
{
return bit_enabled( data, number ) ? word : std::string( ' ', word.length() );
}
const size_t data = 7;
const boost::array< std::string, 3 > vocabulary = { "a", "b", "c" };
std::vector< std::string > result;
std::transform(
vocabulary.begin(),
vocabulary.end(),
boost::counting_iterator< size_t >(0),
back_inserter( result ),
boost::bind( &select_word, _1, data, _2 )
);
Также, возможно, если вы определите битовый итератор или будете использовать некоторый битовый контейнер, вы можете использовать boost :: zip_iterator для итерации обоих контейнеров.
EDIT:
Вчера я обнаружил интересную статью , в которой содержится стандарт определения побочного эффекта.
Стандарт определяет побочный эффект как
следует: доступ к объекту
обозначается изменчивым значением,
изменение объекта, вызов библиотеки
Функция ввода / вывода или вызов функции
что делает любая из этих операций
все побочные эффекты, которые являются изменениями в
состояние исполнения
окружающая среда.
EDIT:
Я надеюсь, что это будет последняя редакция.
Меня всегда убеждали, что «нет побочного эффекта» означает:
f (a) всегда должно быть равно f (a). (f не зависит от среды выполнения: память / процессор / глобальные переменные / переменные-члены, как в вашем случае и т. д.).
«Не вызывать побочный эффект» означает - не изменять среду исполнения.
Но в стандарте c ++ у нас есть более низкое определение побочного эффекта.
То, что вы делаете в вашем примере, называется Stateful функтор.
Стандарт не говорит о функторах «Statefull», но также не говорит о количестве копий вашего функтора - вы не могли использовать этот трюк, потому что это неуказанное поведение.
См. Список стандартных проблем с библиотекой (похожая проблема для предиката):
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#92