Общее программирование с концепциями, конфликтующими с конструктором копирования

Я пытаюсь использовать универсальный стиль кодирования, чтобы обернуть API ограниченной концепции поверх общих стеков.
Проблема, с которой я сталкиваюсь, состоит в том, что один из моих конструкторов, самый важный, который использует шаблонный стек, переопределяет мой конструктор копирования.
У меня есть суть рассматриваемого класса, некоторый тестовый код и ошибка, которую я получаю от компилятора здесь: https://gist.github.com/biot023/5178831

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

Может ли кто-нибудь посоветовать, как я мог бы явно вызвать конструктор копирования (что мне действительно нужно сделать в моем тестовом коде), или, может быть, показать мне, где я ошибаюсь?

2

Решение

Проблема в том, что ваш шаблон конструктора лучше соответствует вашему конструктору копирования:

// Copy constructor
WrappedStack( const WrappedStack &other )

// Constructor template
template <typename S>
WrappedStack( S &stack )

Когда создается экземпляр объекта типа WrappedStack<T> (где T это учебный класс Параметр шаблона), экземпляр сигнатуры шаблона конструктора будет выглядеть так:

WrappedStack( WrappedStack<T> &stack )

Это лучше, чем конструктор копирования, если тип аргумента не constквалифицированным, потому что не требует const преобразование. Поэтому шаблон конструктора будет выбран по разрешению перегрузки, а его тело будет создано, что приведет к ошибке, с которой вы столкнулись.

Чтобы заставить компилятор использовать конструктор копирования, когда это необходимо, вы можете использовать SFINAE, чтобы вызвать ошибку замещения при создании экземпляра шаблона конструктора с объектом типа WrappedStack<T>или типа, который неявно преобразуется в WrappedStack<T>, Например:

#include <type_traits>

template<
typename S,
typename std::enable_if<
!std::is_convertible<S, WrappedStack<T> const&>::value
>::type* = nullptr>
WrappedStack( S &stack ) : __stack( new wrapped_stack_t<S, T>( stack ) ) {}

Смотрите живой пример этого успешно компилируется.

1

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

Других решений пока нет …