当前位置:  开发笔记 > 编程语言 > 正文

C++ std :: transform副作用

如何解决《C++std::transform副作用》经验,为你挑选了1个好方法。

我像这样实现了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的解决方案来避免可能出现的问题,请引用标准.

谢谢.

编辑:

我知道变换算法标准中的"无副作用"要求.我无法找到同一标准中的仿函数的"副作用".

也许这个任务有一些好看的类似解决方案?



1> bayda..:

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

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有