C++:如果替换 typedef,可以解决不明确的重载

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

考虑以下用于向量和矩阵乘法的代码片段:

#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;
}

我定义了 2 个 operator* 重载,其中第二个显式使用矩阵。

这将导致 GCC 5.2 上出现 "ambigous overload" 错误,但在我看来,第二个重载比第一个重载更专业。

我现在替换第二个重载中的 typedef:

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

变为:

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

编辑:

我打错了一个小错...这就是解决方案起作用的原因,我交换了 NL,所以 b 的类型是 const vec<vec<U,L>,N>& b

只有这个错字才能正常解决过载问题。

我的问题是:这种行为是标准明确定义的还是错误?

使用 VS2015:

你的代码

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.
}

结果

Error   C2593   'operator *' is ambiguous

歧义源于这样一个事实,即在 vec<T, N> operator*(const vec<T, N>& a, const vec<U, N>& b) 中 T 可以解释为 vec<T,M>

如果我按照你的建议将它们替换为

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.
}

结果不变。

Error   C2593   'operator *' is ambiguous

您确定您的解决方案吗?也许你不考虑const?