现在我有2类A和B:
class A {
};
class B : public A {
};
正在尝试将B的REF实例分配给A类ref变量:
Ref<B> t;
Ref<A> t2(t);
这实际上应该编译,但是我得到了最后2个构造函数(使用可转换类型的构造函数)提到的错误(clang),这实际上应该为该分配启动。需要做些什么才能在这里进行模板参数扣除工作?
您正在错误地使用
std::enable_if
12:
template<typename T2,
typename =
typename std::enable_if<std::is_convertible<T2*, T*>::value>::type>
Ref(Ref<T2> const& value);
ther,第二个模板参数被默认为如果不转换为T2*
the,这将是您想要的:
如果是T1*
,那么这等同于:
std::is_convertible<T2*, T*>::value
true
template<typename T2, typename = void> // Ok, well-formed
Ref(Ref<T2> const& value);
1如果您可以访问C ++14.
template<typename T2, typename = /* Something ill-formed */>
Ref(Ref<T2> const& value);
代替std::enable_if
2
这是一种可能性,另一个是使用
template<typename T2, typename T2> // Well-formed, but T2 cannot be deduced
Ref(Ref<T2> const& value);
(或类似的东西),但我更喜欢T2
版的版本。在一般情况下,它们并不是严格等同的,但是在这种确切的情况下,它们并不重要。
@Holt的答案很好,正确地说明了如何使用
typename std::enable_if<>::type
。在任何情况下,在这种情况下,您根本不需要使用它。 这里足够了,错误消息对此会更好:
std::enable_if_t<>
std::enable_if_t<..., int> = 0
会给您这样的错误:
Error:静态断言失败:! static_assert(std :: is_convertible :: value,“!”);sfinae表达式通常用于(我说)
typename = ...
将默认构造函数和构造函数合并为std::enable_if
。
static_assert
等于template<typename U>
Ref(Ref<U> const& value) {
static_assert(std::is_convertible<U, T>::value, "!");
// whatever you want
}
template<typename U>
Ref(Ref<U> &&value) {
static_assert(std::is_convertible<U, T>::value, "!");
// whatever you want
}
C
。 您的摘要错过了。使用
拷贝和交换成语,您可以使用它来对测试进行分解
A
:
Ref<A> t3(Ref<C>{});