vendredi 11 septembre 2020

error C2668 ambiguous templated overload, works on GCC and CLang

I am getting MSVC C2668 error on this code:

#include <vector>
#include <functional>

class A {
public:
    class B {
    public:
        bool isValid() const {return true;}
        void foo() const {};
    };
    std::vector<B> container;
};

template <class T>
inline void MyForEach(const T &m, std::function<void (const typename T::B &)> action) {
    for(auto b : m.container)
        if(b.isValid())
            action(b);
}

template <class T>
inline void MyForEach(T &m, std::function<void (typename T::B &)> action) {
    for(auto b : m.container)
        if(b.isValid())
            action(b);
}

void bar(const A& obj) {
    MyForEach(obj, [&](const A::B& b){
        b.foo();
    });
}

int main(int, char *[]) {
    A obj;
    bar(obj);
    return 0;
}

It seems that MSVC is not able to disambiguate the constness of the A object:

note: may be 'void MyForEach<const A>(T &,std::function<void (A::B &)>)'
        with
        [
            T=const A
        ]
note: or 'void MyForEach<A>(const T &,std::function<void (const A::B &)>)'
        with
        [
            T=A
        ]

Is there something that cannot be disambiguated in this code? How can I do to have this working with proper const-correctness? GCC and CLang build without errors. I am using VS 2019, v16.7.3 with MSVC 16.6.30225.117.

Aucun commentaire:

Enregistrer un commentaire