C++ 使用auto和decltype使函数返回其类的类型。如何使其返回值而不是引用?
我试图创建一个通用的、纯虚拟的矩阵类,它支持返回新矩阵的方法。当然,如果其中一个方法用于矩阵的子类,它应该返回子类类型的内容,而不是矩阵 目前我的代码是这样的:C++ 使用auto和decltype使函数返回其类的类型。如何使其返回值而不是引用?,c++,c++11,polymorphism,auto,decltype,C++,C++11,Polymorphism,Auto,Decltype,我试图创建一个通用的、纯虚拟的矩阵类,它支持返回新矩阵的方法。当然,如果其中一个方法用于矩阵的子类,它应该返回子类类型的内容,而不是矩阵 目前我的代码是这样的: class Matrix { virtual auto transposed() const -> decltype (*this) = 0 ; } ; class DenseMatrix : Matrix { auto transposed() const -> decltype (*this)
class Matrix
{
virtual auto transposed() const -> decltype (*this) = 0 ;
} ;
class DenseMatrix : Matrix
{
auto transposed() const -> decltype (*this)
{
DenseMatrix res ;
// Do some magic
return res ;
}
} ;
但是,由于decltype(*this)的类型是DenseMatrix&而不是DenseMatrix,因此代码失败,因为它最终返回了对局部变量的引用
<>我如何告诉C++我要返回一个值而不是引用?或者,有没有更干净的方法来实现返回调用它们的类类型的虚拟函数?下面的内容是即兴的,没有经过完全测试。然而,我发现自己在想,众所周知的handle/body习惯用法是否能很好地满足您的需求。它的工作原理是将
矩阵
变成一个指向实现的指针(您当前称之为矩阵
)。然后派生客户机从实现派生,而不是从矩阵本身派生
下面是一个小草图:
#include <memory>
class Matrix
{
public:
class Imp
{
public:
virtual ~Imp() = default;
virtual auto transposed() const -> std::unique_ptr<Imp> = 0;
};
private:
std::unique_ptr<Imp> data_;
public:
Matrix() = default;
explicit Matrix(std::unique_ptr<Imp> data)
: data_(std::move(data)) {}
auto transposed() const -> Matrix
{
return Matrix(data_ ? data_->transposed() : nullptr);
}
};
class DenseMatrix
: public Matrix::Imp
{
public:
virtual auto transposed() const -> std::unique_ptr<Imp>
{
std::unique_ptr<DenseMatrix> res(new DenseMatrix);
// Do some magic
return std::move(res);
}
};
#包括
类矩阵
{
公众:
类Imp
{
公众:
virtual~Imp()=默认值;
虚拟自动转置()const->std::unique\u ptr=0;
};
私人:
std::唯一的ptr数据;
公众:
矩阵()=默认值;
显式矩阵(std::unique_ptr数据)
:data_(std::move(data)){
自动转置()常量->矩阵
{
返回矩阵(数据→数据→转置():nullptr);
}
};
类密度矩阵
:公共矩阵::Imp
{
公众:
虚拟自动转置()常量->标准::唯一\u ptr
{
std::唯一ptr res(新密度矩阵);
//施点魔法
返回std::移动(res);
}
};
这意味着您的所有数据都必须在堆上。但在这种情况下,这种情况很可能会发生
外部客户端只处理矩阵
,它不是基类,而是指向基类指针的“句柄”。新的实现源于内部基类,而不是矩阵
类本身
它不是一直工作的。我还忽略了一些细节,比如客户将如何指定他想要的(例如,
DenseMatrix
,而不是其他类型的矩阵。但是这种通用的数据结构有时非常有用。以下内容是即兴的,没有经过充分测试。然而,我发现自己在想,众所周知的handle/body习惯用法是否能很好地满足您的需求。它的工作原理是将矩阵
变成一个指向实现的指针(您当前称之为矩阵
)。然后派生客户机从实现派生,而不是从矩阵本身派生
下面是一个小草图:
#include <memory>
class Matrix
{
public:
class Imp
{
public:
virtual ~Imp() = default;
virtual auto transposed() const -> std::unique_ptr<Imp> = 0;
};
private:
std::unique_ptr<Imp> data_;
public:
Matrix() = default;
explicit Matrix(std::unique_ptr<Imp> data)
: data_(std::move(data)) {}
auto transposed() const -> Matrix
{
return Matrix(data_ ? data_->transposed() : nullptr);
}
};
class DenseMatrix
: public Matrix::Imp
{
public:
virtual auto transposed() const -> std::unique_ptr<Imp>
{
std::unique_ptr<DenseMatrix> res(new DenseMatrix);
// Do some magic
return std::move(res);
}
};
#包括
类矩阵
{
公众:
类Imp
{
公众:
virtual~Imp()=默认值;
虚拟自动转置()const->std::unique\u ptr=0;
};
私人:
std::唯一的ptr数据;
公众:
矩阵()=默认值;
显式矩阵(std::unique_ptr数据)
:data_(std::move(data)){
自动转置()常量->矩阵
{
返回矩阵(数据→数据→转置():nullptr);
}
};
类密度矩阵
:公共矩阵::Imp
{
公众:
虚拟自动转置()常量->标准::唯一\u ptr
{
std::唯一ptr res(新密度矩阵);
//施点魔法
返回std::移动(res);
}
};
这意味着您的所有数据都必须在堆上。但在这种情况下,这种情况很可能会发生
外部客户端只处理矩阵
,它不是基类,而是指向基类指针的“句柄”。新的实现源于内部基类,而不是矩阵
类本身
它不是一直工作的。我还忽略了一些细节,比如客户将如何指定他想要的(例如,DenseMatrix
,而不是其他类型的矩阵。但是这种通用数据结构有时非常有用。如果您想从类型中删除引用,只需使用std::remove\u reference
然而,这类问题的另一个通用解决方案是使用静态多态性(也称为CRTP):
struct MatrixBase
{
// here goes all stuff which is independent of the actual matrix,
// like number of rows, columns, etc.
};
template<typename Derived>
struct Matrix : public MatrixBase
{
virtual auto transposed() const -> Derived
{
return static_cast<Derived const&>(*this).transposed();
}
// ...
};
struct DenseMatrix : public Matrix<DenseMatrix>
{
virtual auto transposed() const override -> DenseMatrix
{ /* implementation */ }
// ...
};
struct MatrixBase
{
//这是所有与实际矩阵无关的东西,
//例如行数、列数等。
};
模板
结构矩阵:公共矩阵库
{
虚拟自动转置()常量->派生
{
返回static_cast(*this).transposed();
}
// ...
};
结构DenseMatrix:公共矩阵
{
虚拟自动转置()常量覆盖->DenseMatrix
{/*实现*/}
// ...
};
这种策略通常比使用基类指针的动态多态性要快一点。例如,库Eigen也使用CRTP。如果要从类型中删除引用,只需使用std::remove\u reference
然而,这类问题的另一个通用解决方案是使用静态多态性(也称为CRTP):
struct MatrixBase
{
// here goes all stuff which is independent of the actual matrix,
// like number of rows, columns, etc.
};
template<typename Derived>
struct Matrix : public MatrixBase
{
virtual auto transposed() const -> Derived
{
return static_cast<Derived const&>(*this).transposed();
}
// ...
};
struct DenseMatrix : public Matrix<DenseMatrix>
{
virtual auto transposed() const override -> DenseMatrix
{ /* implementation */ }
// ...
};
struct MatrixBase
{
//这是所有与实际矩阵无关的东西,
//例如行数、列数等。
};
模板
结构矩阵:公共矩阵库
{
虚拟自动转置()常量->派生
{
返回static_cast(*this).transposed();
}
// ...
};
结构DenseMatrix:公共矩阵
{
虚拟自动转置()常量覆盖->DenseMatrix
{/*实现*/}
// ...
};
这种策略通常比使用基类指针的动态多态性要快一点。例如,库Eigen也使用CRTP。不能使用ab值