Commit 6141d71a authored by Kenton Varda's avatar Kenton Varda

Fix MSVC: Don't specialize constructor with EnableIf params.

It appears that MSVC treats the specialization of this templated constructor as if it were an overload, causing the selection of constructor to be ambiguous. It only does this if the second template parameter (the EnableIf) if present; otherwise the specialization works correctly.

As a work-around, I refactored the code to avoid specializing the constructor. Instead, we add a static method that encapsulates the differences, which the constructor calls.
parent 1c0073e3
......@@ -169,9 +169,7 @@ public:
: disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; }
template <typename U, typename = EnableIf<canConvert<U*, T*>()>>
inline Own(Own<U>&& other) noexcept
: disposer(other.disposer), ptr(other.ptr) {
static_assert(__is_polymorphic(T),
"Casting owned pointers requires that the target type is polymorphic.");
: disposer(other.disposer), ptr(cast(other.ptr)) {
other.ptr = nullptr;
}
inline Own(T* ptr, const Disposer& disposer) noexcept: disposer(&disposer), ptr(ptr) {}
......@@ -254,25 +252,28 @@ private:
}
}
template <typename U>
static inline T* cast(U* ptr) {
static_assert(__is_polymorphic(T),
"Casting owned pointers requires that the target type is polymorphic.");
return ptr;
}
template <typename U>
friend class Own;
friend class Maybe<Own<T>>;
};
template <>
template <typename U, typename>
inline Own<void>::Own(Own<U>&& other) noexcept
: disposer(other.disposer),
ptr(_::castToVoid(other.ptr)) {
other.ptr = nullptr;
template <typename U>
inline void* Own<void>::cast(U* ptr) {
return _::castToVoid(ptr);
}
template <>
template <typename U, typename>
inline Own<const void>::Own(Own<U>&& other) noexcept
: disposer(other.disposer),
ptr(_::castToConstVoid(other.ptr)) {
other.ptr = nullptr;
template <typename U>
inline const void* Own<const void>::cast(U* ptr) {
return _::castToConstVoid(ptr);
}
namespace _ { // private
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment