У меня есть тип шаблона, который параметризован определенным типом указателя. (как итератор). Я хочу, чтобы этот тип можно было неявно преобразовать в свою версию с квалификатором const (например, thing<const int*>(const thing<int*>&
). Я хочу, чтобы этот конструктор был отключен, когда указатель уже равен const
, поскольку он конфликтует с конструктором копирования по умолчанию. В настоящее время у меня есть что-то похожее на этот фрагмент кода:
#include <type_traits>
template <typename Ptr>
struct traits {
using ptr_type = Ptr;
static constexpr bool is_const = std::is_const_v<std::remove_pointer_t<ptr_type>>;
template <typename _Ptr> using rebind = traits<_Ptr>;
};
template <typename Traits>
struct thing {
using ptr_type = typename Traits::ptr_type;
using non_const_ptr_type = std::add_pointer_t<std::remove_const_t<std::remove_pointer_t<ptr_type>>>;
using non_const_traits_type = typename Traits::template rebind<non_const_ptr_type>;
thing(ptr_type p = nullptr) : ptr_(p) {}
thing(const thing&) = default;
template <typename = std::enable_if_t<Traits::is_const>>
thing(const thing<non_const_traits_type>& other) :
ptr_(const_cast<ptr_type>(other.ptr_)) {}
ptr_type ptr_;
template <typename> friend struct thing;
};
int main() {
thing<traits< int*>> t;
thing<traits<const int*>> j(t);
}
Тип thing
получает свой параметр из типа характеристик, потому что это более точно представляет мой реальный код. Я пытался отключить конструктор с помощью std::enable_if
, но по какой-то причине компилятор продолжает жаловаться на enable_if
в non-const thing
.
error: no type named 'type' in 'struct std::enable_if<false, void>'
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
Помещение enable_if
в список аргументов конструктора также не помогает. Скомпилировано с помощью GCC 8 с -std=c++17
. Вот ссылка Godbolt с кодом.
Traits::is_const
имеет значение false. - person Corristo   schedule 01.01.2019thing()
,thing(ptr_type)
иthing(const thing&)
? Я не хочу, чтобы четвертый конструктор существовал, когдаTraits::is_const
равноfalse
. - person Ron   schedule 01.01.2019thing<traits<int*>> t;
. Следует выбратьthing(ptr_type)
. - person   schedule 01.01.2019Ptr
неconst
thing(const thing&)
иthing(const thing<non_const_traits_type>&)
имеют одинаковую подпись. - person Ron   schedule 01.01.2019