是std :: is_convertible共变体还是反变体?

时间:2018-02-24 21:18:44

标签: c++ c++11 typetraits

根据cppreferencetemplate < class To, class From > To test() { return std::declval< From >(); } 应该表现得好像跟随虚构函数的形成:

std::is_convertible< From, To >::value

这意味着,如果trueTo协变,From将评估为From(换句话说,Tostd::is_convertible< From, To >::value的基类{1}},true应评估为struct Base {}; struct Derived : public Base {}; )。

我们说我们有两个班级。

test< Base*, Derived* >()

现在,如果我们调用虚构的测试方法,test< Derived*, Base* >()is_convertible< Base*, Derived* >实际上都会很好地形成,因为即使正式返回类型是指向基类的指针,也可以返回指向派生类的指针。但is_convertible< Derived*, Base* >std::is_convertible_v< Base*, Derived* >的结果会有所不同(is_convertible等于false。此特征的描述是否准确?

修改

这是我尝试实施template < class T, class U > U convert() { return std::declval< T >(); } template < class T, class U, bool isTVoid = std::is_void_v< T >, bool isUVoid = std::is_void_v< U >, class = void > struct is_convertible_helper : public std::false_type {}; template < class T, class U > struct is_convertible_helper< T, U, false, false, std::void_t< decltype(convert< T, U >()) > > : public std::true_type {}; template < class T, class U > struct is_convertible_helper< T, U, false, true, void > : public std::false_type {}; template < class T, class U > struct is_convertible_helper< T, U, true, false, void > : public std::false_type {}; template < class T, class U > struct is_convertible_helper< T, U, true, true, void > : public std::true_type {}; template < class T, class U > struct is_convertible : public is_convertible_helper< T, U > {}; 特质

is_convertible< A*, B* >::value

为什么我问这个问题的原因是,is_convertible< B*, A* >::valuetrue都评估为for(int i=1; i<3; i++) { for(int j =1; j<=3; j++{ System.out.println(i+j); } }

2 个答案:

答案 0 :(得分:2)

  

test< Base*, Derived* >()test< Derived*, Base* >()实际上都会很好地形成。

不正确。

test<Derived*, Base*>()格式不正确,因为Base*无法转换为Derived*

https://ideone.com/N73ROY处查看问题。

  

is_convertible< Base*, Derived* >is_convertible< Derived*, Base* >的结果会有所不同(std::is_convertible_v< Base*, Derived* >等于false)

这是正确的行为。

  

这个特性的描述准确吗?

你的困惑源于第一个声明。因为,这是不正确的,其余的答案应该是有道理的。

答案 1 :(得分:0)

从类型A到类型B的转换以及类型A和类型B之间的子类型关系是非常不同的事情。

如果确实A是B的子类型,那么B可以转换为A(好吧,可能有切片,假设复制ctors可用等等,但实际上你会将B&amp;转换成A&amp; A; ),相反的方向肯定不是真的。 intdouble是可互换的,显然不是彼此的子类型。

所以我认为你有点偏离基础试图将这些概念联系起来 - 而不是详细介绍。