Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: ambigous overload can be resolved if typedefs are replaced

Consider the following code snippet for vector and matrix multiplication:

#include <array>

template<typename T,size_t N> using vec = std::array<T,N>;

template<typename T,size_t N,size_t M> using mat = vec<vec<T,M>,N>;

template<typename T,typename U,size_t N> 
vec<T,N> operator*(const vec<T,N>& a,const vec<U,N>& b){
    return {}; //implement componentwise mult.
}

template<typename T,typename U,size_t N,size_t M,size_t L>
mat<T,L,M> operator*(const mat<T,N,M>& a,const mat<U,L,N>& b){
    return {}; //implement matrix mult.
}

int main(){
    mat<float,4,4> a,b;
    auto c = a * b;
}

I define 2 operator* overloads, where the second one explicitly uses matrices.

This will result in an "ambigous overload" error on GCC 5.2, although in my opinion the second overload is more specialized than the first one.

I now replace the typedefs in the second overload:

mat<T,L,M> operator*(const mat<T,N,M>& a,const mat<U,L,N>& b)

becomes:

mat<T,L,M> operator*(const vec<vec<T,M>,N>& a,const vec<vec<U,N>,L>& b)

Edit:

I made a small typo... thats why the resolution worked, I swapped N and L, so the type of b was const vec<vec<U,L>,N>& b.

Only with this typo the overload can be resolved normally.

My question is: Is this behavior welldefined by the standard or a bug?

like image 467
tly Avatar asked Oct 06 '15 15:10

tly


1 Answers

With VS2015:

your code

template<typename T, typename U, size_t N>
vec<T, N> operator*(const vec<T, N>& a, const vec<U, N>& b) {
    return{}; //implement componentwise mult.
}

template<typename T, typename U, size_t N, size_t M, size_t L>
mat<T, L, M> operator*(const mat<T, N, M>& a, const mat<U, L, N>& b) {
    return{}; //implement matrix mult.
}

results in

Error   C2593   'operator *' is ambiguous

Ambiguity derives from the fact that in vec<T, N> operator*(const vec<T, N>& a, const vec<U, N>& b) T can be interpreted as a vec<T,M>.

And if I replace them as you suggested with

template<typename T, typename U, size_t N>
vec<T, N> operator*(const std::array<T, N>& a, const std::array<U, N>& b) {
    return{}; //implement componentwise mult.
}


template<typename T, typename U, size_t N, size_t M, size_t L>
mat<T, L, M> operator*(const vec<vec<T, M>, N>& a, const vec<vec<U, N>, L>& b) {
    return{}; //implement matrix mult.
}

the results doesn't change.

Error   C2593   'operator *' is ambiguous

Are you sure about your solution? Maybe you are not considering const?

like image 68
Lorenzo Belli Avatar answered Nov 19 '22 10:11

Lorenzo Belli