Я пытаюсь использовать универсальный стиль кодирования, чтобы обернуть API ограниченной концепции поверх общих стеков.
Проблема, с которой я сталкиваюсь, состоит в том, что один из моих конструкторов, самый важный, который использует шаблонный стек, переопределяет мой конструктор копирования.
У меня есть суть рассматриваемого класса, некоторый тестовый код и ошибка, которую я получаю от компилятора здесь: https://gist.github.com/biot023/5178831
Я хочу иметь возможность использовать семантику значений со стеками, которые я создаю, что я могу, просто назначая их вектору. Тем не менее, это дает мне проблему с конструктором копирования.
Может ли кто-нибудь посоветовать, как я мог бы явно вызвать конструктор копирования (что мне действительно нужно сделать в моем тестовом коде), или, может быть, показать мне, где я ошибаюсь?
Проблема в том, что ваш шаблон конструктора лучше соответствует вашему конструктору копирования:
// 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 ) ) {}
Смотрите живой пример этого успешно компилируется.
Других решений пока нет …