2013-12-13 38 views
2

歧義超載我有一個矩陣類和我想能夠:矩陣加法:關於「操作符+」

1)添加2矩陣,C = A + B;

2)添加一個矩陣和標量, C = a + B;C = A + b;

我得到一個警告/錯誤(取決於編譯器標誌)說,函數調用是一把雙刃劍:

g++ test.cpp -std=c++11 

test.cpp: In function ‘int main()’: 
test.cpp:111:16: error: ambiguous overload for ‘operator+’ (operand types are ‘matrix<double>’ and ‘matrix<int>’) 
    auto C = A + B; 
       ^
test.cpp:111:16: note: candidates are: 
test.cpp:56:55: note: matrix<decltype ((declval<T>() + declval<U>()))> matrix<T>::operator+(const matrix<U>&) const [with U = int; T = double; decltype ((declval<T>() + declval<U>())) = double] 
matrix<decltype(std::declval<T>()+std::declval<U>())> matrix<T>::operator+(const matrix<U> &B) const 
                ^
test.cpp:76:57: note: matrix<decltype ((declval<V>() + declval<U>()))> operator+(const U&, const matrix<V>&) [with V = int; U = matrix<double>; decltype ((declval<V>() + declval<U>())) = matrix<double>] 
matrix<decltype(std::declval<V>() + std::declval<U>())> operator+(const U &a, const matrix<V> &B) 
                 ^
test.cpp:90:57: note: matrix<decltype ((declval<V>() + declval<U>()))> operator+(const matrix<U>&, const V&) [with V = matrix<int>; U = double; decltype ((declval<V>() + declval<U>())) = matrix<double>] 
matrix<decltype(std::declval<V>() + std::declval<U>())> operator+(const matrix<U> &A, const V &b) 

下面是一個MWE:

#include <iostream> 
#include <vector> 
#include <array> 

template<class T> 
class matrix 
{ 
public: 
    matrix(); 
    matrix(const size_t &d1, const size_t &d2); 
    T& operator()(const size_t &i, const size_t &j); 
    T operator()(const size_t &i, const size_t &j) const; 

    template<class U> 
    matrix<decltype(std::declval<T>()+std::declval<U>())> operator+(const matrix<U> &B) const; 

    size_t size(const size_t &n) const; 

private: 
    std::vector<T> mData; 
    std::array<size_t,2> mSize; 
}; 

template<class T> 
matrix<T>::matrix() : mData() 
{ 
    for(size_t ii = 0; ii < 2; ii++) 
    { 
     mSize[ii] = 0; 
    } 
} 

template<class T> 
matrix<T>::matrix(const size_t & d1, const size_t & d2) : mData() 
{ 
    mSize[0] = d1; 
    mSize[1] = d2; 

    mData.resize(d1*d2); 
} 

template<class T> 
T& matrix<T>::operator()(const size_t &i, const size_t &j) 
{ 
    return mData[j*mSize[0] + i]; 
} 

template<class T> 
T matrix<T>::operator()(const size_t &i, const size_t &j) const 
{ 
    return mData[j*mSize[0] + i]; 
} 

template<class T> 
template<class U> 
matrix<decltype(std::declval<T>()+std::declval<U>())> matrix<T>::operator+(const matrix<U> &B) const 
{ 
    matrix<decltype(std::declval<T>()+std::declval<U>())> C(mSize[0],mSize[1]); 
    for(size_t ii = 0; ii < mSize[0]; ii++) 
    { 
     for(size_t jj = 0; jj < mSize[1]; jj++) 
     { 
      C(ii,jj) = this->mData[jj*mSize[0] + ii] + B(ii,jj); 
     } 
    } 
    return C; 
} 

template<class T> 
size_t matrix<T>::size(const size_t &n) const 
{ 
    return mSize[n-1]; 
} 

template<class V, class U> 
matrix<decltype(std::declval<V>() + std::declval<U>())> operator+(const U &a, const matrix<V> &B) 
{ 
    matrix<decltype(std::declval<V>() + std::declval<U>())> C(B.size(1),B.size(2)); 
    for(size_t ii = 0; ii < B.size(1); ii++) 
    { 
     for(size_t jj = 0; jj < B.size(2); jj++) 
     { 
      C(ii,jj) = a + B(ii,jj); 
     } 
    } 
    return C; 
} 

template<class V, class U> 
matrix<decltype(std::declval<V>() + std::declval<U>())> operator+(const matrix<U> &A, const V &b) 
{ 
    matrix<decltype(std::declval<V>() + std::declval<U>())> C(A.size(1),A.size(2)); 
    for(size_t ii = 0; ii < A.size(1); ii++) 
    { 
     for(size_t jj = 0; jj < A.size(2); jj++) 
     { 
      C(ii,jj) = A(ii,jj) + b; 
     } 
    } 
    return C; 
} 

int main() 
{ 
    matrix<double> A(3,3); 
    A(0,0) = 1.5; 

    matrix<int> B(3,3); 
    B(0,0) = 1; 

    auto C = A + B; 

    std::cout << C(0,0) << std::endl; 
} 

問:爲什麼會收到這樣的警告/錯誤(取決於編譯器標誌)?我如何解決這個問題,而無需更改所需的界面?

+0

這種歧義的解釋是[here](http://stackoverflow.com/questions/3519282/why-is-this-ambiguity-here)。 – jrok

回答

1

看來,成員函數

template<class U> 
matrix<decltype(std::declval<T>()+std::declval<U>())> operator+(const matrix<U> &B) const; 

是多餘的功能

template<class V, class U> 
matrix<decltype(std::declval<V>() + std::declval<U>())> operator+(const matrix<U> &A, const matrix<V> &B) 

刪除其中之一。

+0

最好刪除成員函數。 – chris

+0

這解決了我的問題。當我嘗試製作MWE時,冗餘功能實際上是一個錯字。我編輯了這個問題以反映我的代碼的真實形式。 @chris的評論是解決方案。 – OSE