При определенных условиях я хочу, чтобы SFINAE покинул конструктор копирования и скопировал оператор присваивания шаблона класса. Но если я это сделаю, создаются конструктор копии по умолчанию и оператор присваивания по умолчанию. SFINAE выполняется на основе тегов, которые я передаю как параметры шаблона класса. Проблема в том, что SFINAE работает только с шаблонами, а оператор-конструктор/присваивание копий не может быть шаблоном. Существует ли обходной путь?SFINAE прочь конструктор копирования
ответ
Это решение использует базовый класс, который условно не копируемыми (по явно маркировки конструктор копирования и копирующий оператор присваивания, как удаляется).
template <bool>
struct NoCopy;
template <>
struct NoCopy<true>
{
// C++11 and later: marking as deleted. Pre-C++11, make the copy stuff private.
NoCopy(const NoCopy&) = delete;
NoCopy& operator=(const NoCopy&) = delete;
protected:
~NoCopy() = default; // prevent delete from pointer-to-parent
};
template <>
struct NoCopy<false>
{
// Copies allowed in this case
protected:
~NoCopy() = default; // prevent delete from pointer-to-parent
};
Пример использования:
template <typename Number>
struct Foo : NoCopy<std::is_integral<Number>::value>
{
Foo() : NoCopy<std::is_integral<Number>::value>{}
{
}
};
int main()
{
Foo<double> a;
auto b = a; // compiles fine
Foo<int> f;
auto g = f; // fails!
}
Примечание: деструктор NoCopy
объявляется protected
, чтобы избежать виртуального наследования (спасибо за подсказку, @Yakk).
Примечание: реализация Уолтера 'copyable' немного более элегантна (поскольку она специализируется только на специальном случае). Но очевидно, что оба подхода работают очень хорошо. – stefan
'NoCopy' должен иметь защищенный деструктор в обоих случаях, так как это класс, который должен быть унаследован, и мы не хотим форсировать« виртуальные »служебные данные. Как вопрос качества реализации. – Yakk
@Yakk Спасибо за комментарий. Я еще не знал об этой детали языка :) – stefan
Метод получения скрещиваемой или не скопируемой базы является стандартной идиомой для этого типа проблемы (см. Также комментарий Штефана). Один из способов его реализации, как это:
template<bool> struct copyable
{
protected:
~copyable() = default;
};
template<> struct copyable<false>
{
copyable(copyable const&) = delete;
copyable&operator=(copyable const&) = delete;
protected:
~copyable() = default;
};
template<bool allow_copy>
class some_class : copyable<allow_copy> { /* ... */ };
Да, это маршрут специализации. – user1095108
@ user1095108 нет, это не маршрут специализации. он использует специализацию как деталь реализации, но он не состоит из специализации вашего 'some_class'. И fianlly, 'copyable' должен иметь' protected: ~ copyable() = default' в обоих случаях. – Yakk
@Yakk Хорошо, я добавил защищенный деструктор. В чем смысл? Является ли он «копируемым» базовым классом? – Walter
- 1. SFINAE enable_if Явный конструктор
- 2. SFINAE: Включить конструктор класса
- 3. Условно отключить конструктор копирования
- 4. конструктор и конструктор копирования
- 5. Конструктор копирования
- 6. SFINAE - Определить конструктор с одним аргументом
- 7. конструктор преобразования или конструктор копирования
- 8. C++ обнаруживает любой конструктор с SFINAE
- 9. Конструктор шаблонов SFINAE с boost :: hana
- 10. Конкретный конструктор копирования C++?
- 11. Конструктор копирования/Оператор присваивания
- 12. Конструктор копирования для шаблонов
- 13. Конструктор копирования в C++
- 14. конструктор копирования не вызывается
- 15. конструктор копирования по адресу
- 16. конструктор копирования с оператором =
- 17. конструктор копирования называется неправильно
- 18. C++ Конструктор копирования Синтаксис
- 19. Ошибка C2558 - конструктор копирования
- 20. конструктор копирования не вызывается
- 21. Конструктор копирования Сомнение
- 22. конструктор копирования, объекты, указатели
- 23. C++ конструктор копирования вызов
- 24. Конструктор копирования шаблона
- 25. Python конструктор копирования
- 26. C++, конструктор копирования путаницы
- 27. Скрытого копирования конструктор C++
- 28. Типы в конструктор копирования
- 29. конструктор копирования не наследуется
- 30. Что такое конструктор копирования?
Используйте базовый класс, который запрещает конструктор/назначение копии в зависимости от аргумента шаблона. – stefan
Поскольку конструктор шаблонов не является конструктором копирования, он также не препятствует тому, чтобы конструктор копирования неявно был объявлен, что иногда будет предпочтительнее, чем ваш конструктор шаблонов, так что это похоже на тупик. Комментарий @ stefan кажется, что это сделало бы для хорошего ответа. – hvd