5

I want to use a lambda expression as custom Compare for a std::set of integers. There are many answers on this site explaining how to do this, for example https://stackoverflow.com/a/46128321/10774939. And indeed,

#include <vector>
#include <set>
#include <iostream>

int main() {

    auto different_cmp = [](int i, int j) -> bool {
        return j < i;
    };

    std::set<int, decltype(different_cmp)> integers(different_cmp);

    integers.insert(3);
    integers.insert(4);
    integers.insert(1);
    for (int integer : integers) {
        std::cout << integer << " ";
    }

    return 0;
}

compiles and outputs

4 3 1

as expected. However, when I try to put this set in a vector with

    std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers;
    vec_of_integers.push_back(integers);

the compiler complains. I'm using Visual Studio 2017 and I get different compiler errors depending on the surrounding code. In the above example, it's

1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\utility(77): error C2664: 'void std::swap(std::exception_ptr &,std::exception_ptr &) noexcept': cannot convert argument 1 from '_Ty' to 'std::exception_ptr &'
1>        with
1>        [
1>            _Ty=main::<lambda_48847b4f831139ed92f5310c6e06eea1>
1>        ]

Most of the errors I've seen so far with this seem to have to do with copying the set.

So my question is:

Why does the above code not work and how can I make it work, while still using a locally defined lambda?

x432ph
  • 400
  • 1
  • 10
  • 3
    I cannot reproduce your error. Please provide a full example that we can copy-paste into our compiler. – DeiDei Dec 11 '18 at 10:08
  • 2
    Reproduction: https://godbolt.org/z/SgVU58 – YSC Dec 11 '18 at 10:29
  • The example really is just the above code, plus the two lines std::vector> vec_of_integers; vec_of_integers.push_back(integers); inserted right before return 0. As others have already answered, this seems to be a bug specific to the MS-compiler. – x432ph Dec 11 '18 at 10:45

1 Answers1

1

This seems to be a bug in MS compiler as it compiles well with GCC and Clang.

To make it work in MS Compiler (Visual Studio 2017) you can do this:

std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers{integers};

This compiles cleanly. See here.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • Aah, not again, MS-compiler, why!? – x432ph Dec 11 '18 at 10:44
  • @x432ph: Yeah. Today itself, I came across three questions related to MS compiler bugs. – P.W Dec 11 '18 at 10:45
  • In the actual code I'm trying to debug, I have to create a vector of variable length. Is there any way to do this without triggering the bug? – x432ph Dec 11 '18 at 10:48
  • @x432ph: Maybe you can try a combination of `resize` and `vector.at(index) = x`. – P.W Dec 11 '18 at 10:53
  • Good idea, but now the bug occurs in other places where I try to modify sets already in the vector. Unfortunately, I guess I have to create a custom implementation of a search tree to make it work reliably for my purposes. – x432ph Dec 11 '18 at 11:17