使返回类型依赖于调用源

Making return-type dependent on source of invocation?

本文关键字:调用 依赖于 返回类型      更新时间:2023-10-16

我写了一个c++类,它表示任意维度NxM的数学矩阵。此外,我还编写了一个向量类,从中派生出来......

template<size_t N, size_t M>
class matrix{ ... };
template<size_t N>
class vector : public matrix<N,1>{ ... };

。这样 N 向量就可以被视为 Nx1 矩阵,例如当涉及到乘以整数值或等维矩阵(或这方面的向量)的加/减时。这背后的想法是避免重复代码 - 我认为这通常是一个崇高的目标。但这是由此产生的问题:

下面是添加的运算符重载,它仅存在于矩阵类中:

matrix<N,M> operator+(const matrix<N,M>& right){
  //calculate some result and use it to construct a new instance
  return matrix<N,M>(result);
}

确保向量类为其矩阵表示提供了一个复制构造函数,应该可以这样说:

vector<3> a(1,2,3);
vector<3> b(3,2,1);
a = a+b; 

但你不能这样说:

(a+b).some_vector_instance_method();

。因为 (A+B) 不是向量。

问题:是否可以实现矩阵运算符+,以便它使返回类型依赖于它的调用源?所以,基本上,如果你在矩阵上调用 +,它应该返回一个矩阵;如果在向量上调用,它应该返回一个向量。

现在您可以执行此操作:

template<typename D>
D operator+(const D& right){
  //calculate result as usual, relying on 'right' to have what it takes
  return D(result);
}

。但它是不安全的。

有什么想法吗?

实现的简单方法是为matrix<M, N>vector<M>实现成员operator+=(),其中后者只是委托给前者,矩阵运算符具有实际操作。然后,使用一些标记operator+()作为这些运算符的非成员运算符实现。以下是简要草图:

#include <iostream>
namespace matrix_operators
{
    struct tag {};
    template <typename T>
    T operator+ (T const& lhs, T const& rhs) {
        return T(lhs) += rhs;
    }
}
template<size_t N, size_t M>
class matrix
    : matrix_operators::tag
{
public:
    matrix<N, M>& operator+= (matrix<N, M> const&) {
        std::cout << "matrix<" << N << ", " << M << "::operator+=()n";
        return *this;
    }
};
template<size_t N>
class vector:
    public matrix<N,1>
{
public:
    vector<N>& operator+= (vector<N> const& other) {
        matrix<N, 1>::operator+= (other);
        return *this;
    }
    void some_other_method() {
        std::cout << "vector<" << N << ">::some_other_method()n";
    }
};
int main()
{
    vector<3> a, b;
    (a + b).some_other_method();
}