C ++ 11编写模板以选择更大整数类型的方法?

时间:2012-09-25 03:40:17

标签: c++ templates c++11 metaprogramming

在C ++ 11的编译时,模板函数中有两个模板参数,两个模板参数都必须是无符号整数类型,我想让一个局部变量具有两个模板参数中任何一个的类型更多位。在C ++ 03中,我可能会写一些类似的东西:

template<bool, class T, class U>
struct pick_first;

template<class T, class U>
struct pick_first<true, T, U> {
    typedef T type;
};

template<class T, class U>
struct pick_first<false, T, U> {
    typedef U type;
};

template<class T, class U>
struct pick_bigger {
    typedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type;
};

// usage
template<class uintX_t, class uintY_t>
void foo() {
    typename pick_bigger<uintX_t, uintY_t>::type mylocal = 0;
    // insert doing stuff with mylocal here
}

我可以利用任何新的C ++ 11功能来简化这个吗?我知道我可以使用可变参数模板使其不仅仅使用一对类型,而不是使用pick_first,我可以编写许多特化,使其适用于新的int_leastX_t和int_fastX_t类型。但我很好奇是否只有一个更好的方法。也许以某种方式利用auto / constexpr / decltype?

2 个答案:

答案 0 :(得分:9)

你的pick_first只是在C ++ 11中的std :: conditional,所以你可以写

template<class T, class U>
struct wider {
    using type = typename std::conditional<sizeof(T) >= sizeof(U), T, U>::type; // I'm using the C++11 type alias feature 1) to educate people about them and 2) because I like them better than typedefs.
};

如果你只是想要一个适合保存某种表达式的结果的类型,并且不一定只需要两种类型中的一种,那么std::common_type或者auto是最好的溶液:

template<class uintX_t, class uintY_t>
void foo() {
    typename std::common_type<uintX_t, uintY_t>::type mylocal = 0;
    // insert doing stuff with mylocal here
}

// or
template<class uintX_t, class uintY_t>
void foo(uintX_t x, uintY_t y) {
    auto mylocal = x + y;
}

并且您的pick_bigger实现中缺少typenametypedef typename pick_first<(sizeof(T) >= sizeof(U)), T, U>::type type;

答案 1 :(得分:2)

由于两种类型都是无符号的,只需执行decltype( T1() + T2() )