неверный ковариантный тип возврата для шаблонного дочернего класса

У меня есть дочерний класс, который наследуется от родительского класса, но дочерний класс также получает аргумент шаблона. Оба класса имеют функцию «клон», которая просто вызывает их конструктор копирования. Я хочу сделать копию виртуальной, чтобы дочерний класс всегда вызывал свою собственную копию.

Вот упрощенная версия проблемы:

#include <iostream>
using namespace std;

class Parent
{
public:
virtual Parent foo() { cout << "Parent Foo\n"; return *this; }
};

template <class T>
class Child : public Parent
{
public:
Child<T> foo() { cout << "Child Foo\n"; return *this; }
};

int main()
{
Child<int> c;

c.foo();

return 0;
}

Кажется, что класс Child должен быть ковариантным с классом Parent. Что мне не хватает? Есть ли способ сохранить виртуальную функцию и шаблон? Благодарю.

РЕДАКТИРОВАТЬ

Возможно, мой предыдущий пример был слишком простым. Вот расширенный простой пример:

#include <iostream>
using namespace std;

class Parent
{
public:
Parent(){}
virtual Parent clone() const { return Parent(*this); }
private:
Parent( Parent const& cpy ) { };
};

template <class T>
class Child : public Parent
{
public:
Child(){}
Child<T> clone() const { return Child<T>(*this); }
private:
Child( Child<T> const& cpy ) {};
};

int main()
{
Child<int> c;
Parent* pc = &c;
pc->clone();

return 0;
}

Я хотел бы, чтобы копия всегда была реальной копией класса, делая копию виртуальной.
Я хотел избежать возврата указателя, но похоже, что я буду вынужден возвращать указатели, чтобы избежать проблемы срезов, упомянутой Дитером Люкингом.

0

Решение

Типы Parent и Child являются не ковариантными, а Parent.& и ребенок& являются.

#include <iostream>
using namespace std;

class Parent
{
public:
virtual Parent& foo() = 0;
};

template <class T>
class Child : public Parent
{
public:
Child& foo() { cout << "Child Foo\n"; return *this; }
};

int main()
{
Child<int> c;
Parent& parent = c.foo();
return 0;
}

С 10.3.7 Виртуальные функции

Тип возврата переопределяющей функции должен быть идентичным
тип возврата переопределенной функции или ковариантный с
классы функций. Если функция D :: f переопределяет функцию
B :: f, возвращаемые типы функций ковариантны, если они удовлетворяют
следующие критерии:

— оба указатели на классы, оба
lvalue ссылки на классы, или оба являются rvalue ссылками на
classes112

— класс в возвращаемом типе B :: f является тем же классом, что и
класс в возвращаемом типе D :: F, или является однозначным и
доступный прямой или косвенный базовый класс класса в возвращении
тип D :: f

— оба указателя или ссылки имеют одинаковые
cv-квалификация и тип класса в возвращаемом типе D :: f имеет
та же квалификация cv или меньше квалификации cv, чем у типа класса
в возвращаемом типе B :: f.

6

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