As already mentioned, you can do this in a one-pass algorithm. You only need to keep track of whether you have seen a character before, and what the position of its first occurence is. Here is a possible implementation:
#include <algorithm>
#include <array>
#include <climits>
#include <cstdint>
#include <string>
std::size_t FirstOccurrenceOfUniqueChar(const std::string& s) {
    std::array<bool, 1 << CHAR_BIT> seen{};
    std::array<std::size_t, 1 << CHAR_BIT> pos;
    pos.fill(s.npos);
    for (std::size_t i = 0; i < s.size(); ++i) {
        auto ch = static_cast<unsigned char>(s[i]);
        pos[ch] = seen[ch] ? s.npos : i;
        seen[ch] = true;
    }
    return *std::min_element(pos.begin(), pos.end());
}
 Note that in the above code, only two std::arrays are used; since there are only a fixed number of characters, you can use a fixed-size container instead of the slower std::list and std::unordered_map.
 Also note that this version returns a std::size_t; this is necessary to support strings longer than an int can represent. Also, std::string::npos is used to indicate that there is no unique character. It's the largest possible value of std::size_t, which is very convenient here.
 Also, if you cast std::string::npos to an int, it will become -1.