gpt4 book ai didi

C++ std::transform 副作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:09 25 4
gpt4 key购买 nike

我已经实现了这样的 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 的解决方案,以避免可能出现的问题。

谢谢。

编辑:

我知道转换算法标准中的“无副作用”要求。我无法在同一标准中找到仿函数的确切“副作用”。

也许这个任务有一些看起来不错的类似 boost 的解决方案?

最佳答案

来自标准:

25.2.3 Transform [lib.alg.transform]
Requires:
op and binary_op shall not have any side effects.

Side Effect ( wikipedia definition )

在你的情况下我们有下一个副作用:

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 来迭代这两个容器。

编辑:
昨天我找到了interest article其中包含标准的副作用定义。

The Standard defines a side effect as follows: Accessing an object designated by a volatile lvalue, modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.

编辑:
我希望这是最新的编辑。
我一直认为“没有副作用”是什么意思:
f(a) 应该始终等于 f(a)。 ( f 独立于执行环境:内存/cpu/全局变量/成员变量,如您的情况等)。
“不产生副作用”的意思是——不改变执行环境。

但在 C++ 标准中,我们对副作用有更多的低级定义。

你在你的例子中所做的事情被命名为 Stateful 仿函数。
标准没有说明“有状态”仿函数,也没有说明仿函数的拷贝数 - 你不能使用这个技巧,因为它是未指定的行为。

参见标准库问题列表(与 predicat 类似的问题):
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#92

关于C++ std::transform 副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/708742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com