-3

I am having trouble dereferencing a found shared_ptr from a vector after std::find. Could someone explain why this is the case?

    extern std::vector< shared_ptr<King::Actor> > selected
    foo(const std::vector<std::shared_ptr<Actor>> &playerUnits)
    {
        std::vector<std::shared_ptr<Actor>>::const_iterator result;
        result = std::find(std::begin(playerUnits), std::end(playerUnits), selected.back());

        if (result != std::end(playerUnits))
            return *std::next(result); // found
        return nullptr;
    }
enter code here

closest answer is https://stackoverflow.com/questions/301959/vector-iterator-not-dereferencable#= I believe it both found it and not the end of the vector, yet it still reports not dereferencable.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Chris
  • 49
  • 4
  • What is your error? Compiler error? Runtime? What is the exact message you had? – vdavid Sep 03 '18 at 23:10
  • 2
    If the found unit is the last one, then you try to dereference off the end – M.M Sep 03 '18 at 23:11
  • The example you have given would not compile, since the return type of `foo()` is invalid. In any event, the problem would not be that an iterator is not dereferencable. It is probably that dereferencing `std::next(result)` gives a result that cannot be converted to the function's return type. You will also find that returning `result` would not compile for the same reason. Whatever that type actually is in your code ..... – Peter Sep 03 '18 at 23:11
  • 2
    I'm not sure why you are returning `*next(result)` instead of `*result`? – Steven W. Klassen Sep 03 '18 at 23:12
  • @StevenW.Klassen his MVCE doesn't give all the details but he probably wants the next one. However, should the container be cyclic, he must check if he reached the element before last in which case the next result should return `std::begin(playerUnits)`. – vdavid Sep 03 '18 at 23:14
  • @Peter this is a runtime error message, the problem you suggest would be a compilation error – M.M Sep 03 '18 at 23:16
  • @M.M thanks. The check I put in for std::end is needed for std::next before dereferencing. The run time error is when the next one is the end. – Chris Sep 03 '18 at 23:22
  • 1
    @Chris maybe you mistakenly think that `std::end` means the last element? – M.M Sep 03 '18 at 23:24
  • @M.M yes, I did think that. Appreciate the insight. – Chris Sep 03 '18 at 23:29

1 Answers1

2
   if (result != std::end(playerUnits))
        return *std::next(result); // found

if the found result is the last one, std::next produces end, which you then dereference.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524