Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用auto和decltype使函数返回其类的类型。如何使其返回值而不是引用?_C++_C++11_Polymorphism_Auto_Decltype - Fatal编程技术网

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值