如何防止复制构造函数在for_each函数的末尾被调用?

How do I prevent the copy constructor being called at the end of the for_each?

本文关键字:调用 函数 each 复制 何防止 构造函数 for      更新时间:2023-10-16

在下面的代码中,我期望看到COD,但实际输出是CODD。我最终确定存在对复制构造函数的隐藏调用,因此输出现在是COUDD

虽然我已经发现了为什么要额外的析构函数调用,但我不明白为什么要生成它,这阻止了我修复它。我认为它必须是从for_each返回一元函数,但由于我没有传递或返回值(或者我不认为我是),那么不应该调用复制构造函数。一切都应该参照。我可以使用指针,但由于test_enc对象应该在调用for_each期间的作用域,因此引用更好。

struct test_enc
{
    test_enc(std::string& ref) : ref_(ref) {
        ref_.push_back('C');
    }
    test_enc(const test_enc& other) : ref_(other.ref_) {
        ref_.push_back('U');
    }
    ~test_enc() {
        ref_.push_back('D');
    }
    void operator()(const char byte) {
        ref_.push_back('O');
    }
    test_enc& operator=(const test_enc&) = delete;
    std::string& ref_;
};
TEST(CheckTestEncoderEncodesExactlyOneByte)
{
    const std::string unencoded_string("M");
    std::string encoded_string;
    std::for_each(unencoded_string.begin(), unencoded_string.end(), test_enc(encoded_string));
    CHECK_EQUAL(3U, encoded_string.size());
    CHECK_EQUAL("COD", encoded_string); // get "COUDD"
}

如何调用test_enc而不需要复制构造函数?

std::for_each按值取一元函子。因此,您无法避免复制,但是您可以通过使用std::reference_wrapper:

来模拟引用语义。
#include <functional>
std::string encoded_string;
test_encoded test_str(encoded_string);
std::for_each(unencoded_string.begin(), 
              unencoded_string.end(), 
              std::ref(test_str));

尝试使用std::reference_wrapper也许?

test_enc func(encoded_string);
std::for_each(unencoded_string.begin(), unencoded_string.end(),
              std::ref(func));

包装器的行为类似于引用,但允许在需要时复制它(不影响底层对象)。

std::for_each返回std::move(f)。test_enc不可移动,因此返回一个副本。添加move构造函数和move赋值操作符以防止复制