2013-12-13 3 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

Объяснение такого рода двусмысленности [здесь] (http://stackoverflow.com/questions/3519282/why-is-this-ambigity-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

Смежные вопросы