Не удалось обновить объект шаблона по параметру функции

В следующем упрощенном коде я пытаюсь что-то вроде этого:

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

Обычно это работает, но в следующем более сложном коде это не работает.
Я думаю, что я что-то упустил по шаблонам.

Почему невозможно сбить с толку 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;
}

0

Решение

Ваш код не работает, потому что вы пытаетесь связать временный container_reference вернулся из row в вашем звонке swap,

Вы просто забыли связать const ссылаться и отмечать сам метод const:

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

Поскольку вы меняете только (неконстантный) контент c и не c само по себе, вам не нужно, чтобы это было изменяемым. Хотя стоит отметить, что это довольно необычно swap где оба аргумента const потому что они только заполнители для реального контента, который поменялся местами.

3

Другие решения

Дайте ему имя, тогда это lvalue и актерский состав:

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

Другой вариант — добавить версию подкачки, которая принимает временные значения:

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

По вопросам рекламы [email protected]