C ++:如果替换了typedef,则可以解决ambigous重载问题

时间:2015-10-06 15:58:15

标签: c++ c++11 operator-overloading

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

#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出现“暧昧过载”错误,但在我看来,第二次过载比第一次过载更专业。

我现在替换第二个重载中的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

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

我的问题是:标准或错误是否很好地定义了这种行为?

1 个答案:

答案 0 :(得分:1)

使用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

结果不会改变。

2015-10-06T11:17:48.403-0400 I CONTROL  Hotfix KB2731284 or later update is not installed, will zero-out data files
2015-10-06T11:17:48.403-0400 I CONTROL  Trying to start Windows service 'MongoDB'
2015-10-06T11:17:48.403-0400 I STORAGE  Service running
2015-10-06T11:17:48.423-0400 I JOURNAL  [initandlisten] journal dir=C:\Program Files\MongoDB\data\db\journal
2015-10-06T11:17:48.424-0400 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2015-10-06T11:17:48.425-0400 I JOURNAL  [initandlisten] 
2015-10-06T11:17:48.425-0400 E JOURNAL  [initandlisten] Insufficient free space for journal files
2015-10-06T11:17:48.425-0400 I JOURNAL  [initandlisten] Please make at least 3379MB available in C:\Program Files\MongoDB\data\db\journal or use --smallfiles
2015-10-06T11:17:48.425-0400 I JOURNAL  [initandlisten] 
2015-10-06T11:17:48.428-0400 I STORAGE  [initandlisten] exception in initAndListen: 15926 Insufficient free space for journals, terminating
2015-10-06T11:17:48.429-0400 I CONTROL  [serviceStopWorker] now exiting
2015-10-06T11:17:48.429-0400 I NETWORK  [serviceStopWorker] shutdown: going to close listening sockets...
2015-10-06T11:17:48.429-0400 I NETWORK  [serviceStopWorker] shutdown: going to flush diaglog...
2015-10-06T11:17:48.429-0400 I NETWORK  [serviceStopWorker] shutdown: going to close sockets...
2015-10-06T11:17:48.429-0400 I STORAGE  [serviceStopWorker] shutdown: waiting for fs preallocator...
2015-10-06T11:17:48.429-0400 I STORAGE  [serviceStopWorker] shutdown: final commit...
2015-10-06T11:17:48.429-0400 I STORAGE  [serviceStopWorker] shutdown: closing all files...
2015-10-06T11:17:48.429-0400 I STORAGE  [serviceStopWorker] closeAllFiles() finished
2015-10-06T11:17:48.429-0400 I CONTROL  [serviceStopWorker] dbexit:  rc: 49

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