我像这样实现了UnaryOperation
struct Converter { Converter( std::size_t value ): value_( value ), i_( 0 ) {} std::string operator() ( const std::string& word ) { return ( value_ & ( 1 << i_++ ) ) ? word: std::string( word.size(), ' ' ); } std::size_t value_; std::size_t i_; };
而且我喜欢它
std::vector v; // initialization of v std::transform( v.begin(), v.end(), std::back_inserter( result ), Converter( data ) );
我的问题是,我可以依赖于我的假设,即算法将按照'Converter :: i_'对应于'v'中元素的数量的顺序调用我的'Converter operator()'.
如果我不能依赖订单或者使用类似stl的解决方案来避免可能出现的问题,请引用标准.
谢谢.
编辑:
我知道变换算法标准中的"无副作用"要求.我无法找到同一标准中的仿函数的"副作用".
也许这个任务有一些好看的类似解决方案?
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迭代两个容器.
编辑:
Yestarday我发现感兴趣的文章包含标准的副作用定义.
标准定义了一个副作用如下:访问由volatile左值指定的对象,修改对象,调用库I/O函数或调用执行任何这些操作的函数都是副作用,这些都是执行环境的状态.
编辑:
我希望它将是最新的编辑.
我总是认为"没有副作用"的意思是:
f(a)应始终等于f(a).(f与执行环境无关:内存/ cpu /全局变量/成员变量,如你的情况等).
"不产生副作用"的意思是 - 不要改变执行环境.
但是在c ++标准中,我们对副作用有更多的低级别定义.
你在你的例子中做了什么,名为Stateful functor.
标准没有说"Statefull"仿函数,但也没有说你的仿函数的副本数量 - 你不能使用这个技巧,因为它是未指定的行为.
请参阅标准库问题列表(类似于谓词的问题):http:
//anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#92