【问题标题】:C++ Write Macro for finding an integer type given another integer type给定另一个整数类型,用于查找整数类型的 C++ 编写宏
【发布时间】:2022-01-22 12:10:30
【问题描述】:

我有一个看起来像这样的函数:

template<class T, class E, class U = T> T function(T input1, E input2) {
    // implementation here
}

我希望U 的默认值是一个宏,而不是上面的声明,它以T 为输入。更具体地说,如果T 是boost::multiprecision::cpp_int,我希望U 的默认值为boost::multiprecision::cpp_int,并且我希望U 的默认值为一个整数,其精度是T 的两倍,用于固定精度@ 987654330@.

我知道第二部分可以通过以下方式完成:

U = boost::uint_t<2 * std::numeric_limits<T>::digits>::fast

如何检查 T 是否为 cpp_int(或 std 和 boost 中的任何其他任意精度整数),并将所有内容放在一个宏中?

编辑:

我发现可以通过以下方式测试任意精度:

std::numeric_limits<T>::is_bounded

我仍然不知道如何将这 2 个测试组合成 1 个宏。

【问题讨论】:

  • 您可以编写一个采用boost::multiprecision::cpp_int 的重载。这样编译器只会在模板上选择那个。
  • 由于 E 类,重载需要模板部分特化,所以这对我不起作用。
  • 不,您不必专门,只需编写另一个没有 T 或 U 的函数,并使用 boost::multiprecision::cpp_int 代替它们。
  • 这可行。我在其他几个模板化函数中使用了这个函数,所以我仍然需要测试这些模板的输入是否是 cpp_int/任意精度,我不知道该怎么做。但我将能够避免编写宏。
  • 您是否有理由为此需要宏?

标签: c++ templates boost macros integer


【解决方案1】:

如果T 的双倍大小大于int64_t,则一种方法是使用boost::multiprecision::cpp_int。

想法:

#include <boost/multiprecision/cpp_int.hpp>

#include <cstddef>
#include <type_traits>

// type trait to get an int of the requested size
template<size_t S>
struct int_size {
    using type = std::conditional_t<S==1, int8_t,
                     std::conditional_t<S==2, int16_t,
                         std::conditional_t<S==4, int32_t,
                             std::conditional_t<S==8, int64_t,
                                                boost::multiprecision::cpp_int>>>>;
};

template<size_t S>
using int_size_t = int_size<S>::type;

然后将U 的大小设为T 或boost::multiprecision::cpp_int(如果它大于int64_t)的两倍:

template<class T, class E, class U = int_size_t<sizeof(T) * 2>> 
T function(T input1, E input2) {
    // implementation here
}

Demo

【讨论】:

  • 这是一个有趣的答案,我不知道条件,所以我必须了解更多关于它们的信息
  • @dancxviii std::conditional 是一个非常简洁的小类模板 + 专业化。查看std::conditional 的“可能的实现”。真的很简单,但是很有帮助。
【解决方案2】:

使用宏定义了一个自定义的 boost 多精度 int,并将函数后端隐藏在另一个检查类型的函数后面。 U 是无效的,因此用户可以选择自定义它。如果 T 是固定精度,则函数调用宏,否则将 cpp_int 作为模板参数传递。自定义 boost int 的类型推导是在编译时完成的,if 语句也可能在编译时进行评估。

#include <limits>
#include <type_traits>

#ifndef BOOST_UINT
#define BOOST_UINT(bit_count) boost::multiprecision::number<boost::multiprecision::cpp_int_backend<bit_count, bit_count, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>
#endif

template<class T, class E, class U = void> T function(T input1, E input2) {
    if(std::is_same<U, void>::value) {
        if(std::numeric_limits<T>::is_bounded) {
            return function_backend<T, E, BOOST_UINT( ((std::numeric_limits<T>::digits + 1) >> 1) << 2)>(input1, input2);
        } else {
            return function_backend<T, E, cpp_int>(input1, input2);
        }
    } else {
        return function_backend<T, E, U>(input, input2);
    }
}

template<class T, class E, class U> T function_backend(T input1, E input2);

【讨论】:

    猜你喜欢
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2012-03-03
    • 1970-01-01
    相关资源
    最近更新 更多