C ++型性状T1和T2之间选择(C++ type traits to select between

2019-07-29 23:43发布

我想一个模板,基于某些条件下两种选择。 例如

struct Base {};

template <typename T1, typename T2>
struct test
{
    // e.g. here it should select T1/T2 that is_base_of<Base>
    typename select_base<T1, T2>::type m_ValueOfBaseType;
};

当然,要条件传递给select_base(使它通用)是有用的,但硬编码的解决方案更容易,以及良好。

下面是我试过的样品溶液,但它总是选择T1: http://ideone.com/EnVT8

现在的问题是如何实现select_base模板。

Answer 1:

C ++ 14(以及以后):

template <typename T, typename U>
struct select_base:
    std::conditional_t<std::is_base_of<T, Base>::value, T, U> {};

本着同样的精神,你可以使用它代替:

template<typename T, typename U>
using select_base = std::conditional_t<std::is_base_of_v<T,Base>, T, U>;

当您使用它们可以看出这两种方法之间的差异。 例如,在第一种情况下,如果你必须使用::type ,而在第二个,你不。 如果有任何依赖型的第一种方法的使用涉及,你必须使用typename为好,以协助编译器。 第二种方法是免费的所有这样的噪声,因而优于这个答案的方法的其余部分。

另外,请注意,您可以用C ++写11相似类型的别名也。


C ++ 11:

template <typename T, typename U>
struct select_base:
    std::conditional<std::is_base_of<T, Base>::value, T, U>::type {};
//                 ^                                       ^~~~~~

C ++ 98:

条件是很容易做到:

template <typename bool, typename T, typename U>
struct conditional { typedef T type; };

template <typename T, typename U>
struct conditional<false, T, U> { typedef U type; };

is_base_of要稍微复杂一些,实现在加速,我不会在这里重现可用。

然后,请参阅C ++ 11。



Answer 2:

如果您使用std::conditional ,而不是if_类模板由@Matthieu在他的回答中实现,那么你的解决方案会减少这样的:

template <typename T, typename U>
struct select_base
{
   typedef typename std::conditional<std::is_base_of<T, Base>::value, T, U>::type base_type;
};

或者简单:

template <typename T, typename U>
struct select_base : std::conditional<std::is_base_of<T, Base>::value, T, U> {};

它看起来甚至更好。

这两种解决方案之间的区别是,在第一个解决方案你嵌套类型给程序员友好的名字,因为我已经给它base_type ,而在第二溶液中的嵌套类型仅仅是type不看那个程序员-友好。

请注意,在上述两种解决方案,你已经使用嵌套类型如任一select_base<T,U>::base_type (在第一溶液)或select_base<T,U>::type (在第二溶液-正因为如此,如果你使用的typename为你写自己在问题本身。

但是,如果改为使用模板的别名,定义如下:

template<typename T, typename U>
using base_type = typename std::conditional<std::is_base_of<T, Base>::value, T, U>::type;

然后就可以使用base_type<T,U>没有任何嵌套型和typename为:

template <typename T1, typename T2>
struct test
{
   //typename select_base<T1, T2>::type m_ValueOfBaseType; //ugly!

   base_type<T1, T2>  m_ValueOfBaseType; //better
};

希望帮助。



文章来源: C++ type traits to select between T1 and T2