简体   繁体   中英

Return a std::set with a custom comparator

I'm trying to write a function to return a std::set with a custom comparator (per the advice from this answer ), as follows:

#include <iostream>
#include <set>

auto GetSet()
{
    const auto cmp = [](auto n1, auto n2) { return n1 < n2; };
    std::set<int, decltype(cmp)> mySet(cmp); // compiler error, see below
    mySet.insert(13);
    mySet.insert(31);
    return mySet;
}
int main()
{
    auto mySet = GetSet();
    for (auto i : mySet)
        std::cout << i << " ";
}

Obviously this is for demonstration purposes, my class is more complex than an int

It works fine in GCC Coliru link , but does not work in VS2019. In VS2019 (using /std:c++17 ) it produces the following error:

Error C2783 'void std::swap(_Ty &,_Ty &) noexcept()': could not deduce template argument for '_Enabled' C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.27.29110\\include\\utility 114

If I change the code to not use the function, and instead have:

int main()
{
    const auto cmp = [](auto n1, auto n2) { return n1 < n2; };
    std::set<int, decltype(cmp)> mySet(cmp);
    mySet.insert(13);
    mySet.insert(31);
    for (auto i : mySet)
        std::cout << i << " ";
}

It works correctly. Is there anything wrong with the above, or is Microsoft being more pedantic, or some kind of compiler bug?

I don't have an answer on what's going wrong (whether GCC is being sloppy or MSVC is being more pedantic), but you can use the following instead:

#include <set>
#include <functional>
auto GetSet()
{
    const auto cmp = [](auto n1, auto n2) { return n1 < n2; };
    std::set<int, std::function<bool(int, int)>> mySet(cmp);
    mySet.insert(13);
    mySet.insert(31);
    return mySet;
}

Which works on both compilers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM