Home > Enterprise >  Why does copy_if not work correctly with STL vectors?
Why does copy_if not work correctly with STL vectors?

Time:10-31

Spent an ocean of time and read a bunch of pages on SO - but it didn't help. My problem is as follows. In my Win32 C application I use the namespace:

using namespace std;

And there are three vectors:

std :: vector <wstring> A;
std :: vector <wstring> B;
std :: vector <wstring> С;

Vector A contains some set of elements, vector B contains a subset of elements from vector A, and vector C is empty - it does not contain elements. I need to fill vector C with those elements from vector A that are not in vector B. For this I do:

std::copy_if(A.begin(), A.end(), std::back_inserter(C),
                    [](const std::wstring & arg)
                    { return (std::find(B.begin(), B.end(), arg) == 
B.end()); });

But as a result, all elements are copied from vector A to vector C. Why? What am I doing wrong? Could this be hindered by the fact that I also use headers:

#include <boost / interprocess / containers / vector.hpp>
#include <boost / interprocess / containers / string.hpp>

or not? Your help will be highly appreciated by me.

Below the contents of vector: "filePath" means "A" and "pathsToUntransmittedFiles" means "C":

enter image description here

Below is text representation of input:

C:\Program Files\7-Zip\7z.dll
C:\Program Files\7-Zip\7z.exe
C:\Program Files\7-Zip\7z.sfx
C:\Program Files\7-Zip\7zCon.sfx
C:\Program Files\7-Zip\7zFM.exe
C:\Program Files\7-Zip\7zG.exe
C:\Program Files\7-Zip\7-zip.chm
C:\Program Files\7-Zip\7-zip.dll
C:\Program Files\7-Zip\7-zip32.dll
C:\Program Files\7-Zip\descript.ion
C:\Program Files\7-Zip\History.txt
C:\Program Files\7-Zip\License.txt
C:\Program Files\7-Zip\readme.txt

CodePudding user response:

You need to pass the lambda function by capturing references like [&](args..) { ... }.

#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

int main()
{
    std::vector<std::wstring> A{L"abcd", L"bcd", L"sss"};
    std::vector<std::wstring> B{L"sss", L"asd", L"bcd"};
    std::vector<std::wstring> C;

    std::copy_if(A.begin(), A.end(), std::back_inserter(C),
                        [&](const std::wstring & arg)
                        { return (std::find(B.begin(), B.end(), arg) == 
    B.end()); });

    for (std::wstring s : C) {
        std::wcout << s << std::endl;
    }
    return 0;
}

CodePudding user response:

I have no problem with your code when add [&]. It's content of the vectors and comparison who cause the promblem. May be something to do with escape characters \.

My code:

#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

int main()
{
    std::vector<std::wstring> A{ 
        L"C:\\Program Files\\7-Zip\\7z.dll"         ,
        L"C:\\Program Files\\7-Zip\\7z.exe"         ,
        L"C:\\Program Files\\7-Zip\\7z.sfx"         ,
        L"C:\\Program Files\\7-Zip\\7zCon.sfx"      ,
        L"C:\\Program Files\\7-Zip\\7zFM.exe"       ,
        L"C:\\Program Files\\7-Zip\\7zG.exe"        ,
        L"C:\\Program Files\\7-Zip\\7-zip.chm"      ,
        L"C:\\Program Files\\7-Zip\\7-zip.dll"      ,
        L"C:\\Program Files\\7-Zip\\7-zip32.dll"    ,
        L"C:\\Program Files\\7-Zip\\descript.ion"   ,
        L"C:\\Program Files\\7-Zip\\History.txt"    ,
        L"C:\\Program Files\\7-Zip\\License.txt"    ,
        L"C:\\Program Files\\7-Zip\\readme.txt"
    };
    std::vector<std::wstring> B{ 
        L"C:\\Program Files\\7-Zip\\7zCon.sfx"      ,
        L"C:\\Program Files\\7-Zip\\7zFM.exe"       ,
        L"C:\\Program Files\\7-Zip\\7zG.exe"        
    
    };
    std::vector<std::wstring> C;

    std::copy_if(A.begin(), A.end(), std::back_inserter(C),
        [&B](const std::wstring& arg)
        { return (std::find(B.begin(), B.end(), arg) ==
            B.end()); });


    for (std::wstring s : C) {
        std::wcout << s << std::endl;
    }
    return 0;
}

Output: enter image description here

  • Related