0

在下面的简化代码中,我尝试这样的事情:

struct A{};
struct B : public A {};
void func(A &a) {}
B b;
func(b);

通常这是有效的,但在以下更复杂的代码中它不起作用。我想我在模板上遗漏了一些东西。

为什么不可能从 to 向上DenseVector<container_reference<std::array<double, 25ull>>>转型container_reference<std::array<double, 25ull> >&

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

using namespace std;


template<class C>
struct container_reference
{
    typedef typename C::iterator iterator;
    container_reference(iterator f, iterator e) : f(f), e(e) {}
    void swap(container_reference &c) { std::swap(*f, *(c.f)); /*...and more*/ }
    iterator f,e;
};

template<typename C>
struct DenseVector : public C { using C::C; };

template<typename C>
struct DenseMatrixRect
{
    typedef DenseVector<container_reference<C>> row_vector;
    row_vector row(unsigned int i)
    {
        auto it = container.begin() + i * width;
        return row_vector(it, it + width);
    }
    C container;
    unsigned int width;
};


int main() 
{
    DenseMatrixRect<std::array<double, 25>> m; m.width = 5;
    m.row(0).swap(m.row(1));
    return 0;
}
4

2 回答 2

3

您的代码失败,因为您尝试将调用中返回的临时 绑定到.container_referencerowswap

您只是忘记绑定const引用并标记方法本身const

void swap(const container_reference &c) const { std::swap(*f, *(c.f)); /*...and more*/ }
//        ^^^^^                         ^^^^^

由于您只交换(非常量)内容c而不是c其本身,因此您不需要它是可修改的。虽然,值得指出的是,这是一个非常不寻常的swap两个参数,const因为它们只是被交换的真实内容的占位符。

于 2014-01-10T17:50:17.113 回答
1

给它一个名字,然后它是一个左值并且演员工作:

auto x = m.row(1);
m.row(0).swap(x);

另一种选择是添加一个需要临时的交换版本:

void swap(container_reference &&c) { std::swap(*f, *(c.f)); /*...and more*/ }
于 2014-01-10T18:03:06.240 回答