Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在编译时将十进制转换为十六进制_C++_Template Meta Programming - Fatal编程技术网

C++ 在编译时将十进制转换为十六进制

C++ 在编译时将十进制转换为十六进制,c++,template-meta-programming,C++,Template Meta Programming,我正在尝试创建一个程序,可以在编译时将十进制数转换为十六进制数。不幸的是,我是元编程新手,我无法在编译时找到这样做的方法。你知道我该怎么做吗 如何在不违反模板元编程原则的情况下表示这样的数字 #包括//标准::反向 #include <algorithm> // std::reverse #include <iterator> // std::begin, std::end #include <iostream> #include

我正在尝试创建一个程序,可以在编译时将十进制数转换为十六进制数。不幸的是,我是元编程新手,我无法在编译时找到这样做的方法。你知道我该怎么做吗

如何在不违反模板元编程原则的情况下表示这样的数字

#包括//标准::反向
#include <algorithm>        // std::reverse
#include <iterator>         // std::begin, std::end
#include <iostream>
#include <tuple>
#include <type_traits>      // std::integral_constant

namespace detail {
    using std::tuple;
    using std::tuple_cat;
    using std::integral_constant;

    template< unsigned x, int n_digits >
    struct Hex_tuple_
    {
        using Type = decltype( tuple_cat(
            typename Hex_tuple_< x & ((1 << 2*n_digits) - 1), n_digits/2 >::Type(),
            typename Hex_tuple_< (x >> 2*n_digits), n_digits/2 >::Type()
            ) );
    };

    template< unsigned x >
    struct Hex_tuple_< x, 1 >
    {
        using Type = tuple< integral_constant< int, x > >;
    };

}  // namespace detail

template< unsigned x >
using Hex_ = typename detail::Hex_tuple_< x, 2*sizeof( x ) >::Type;

template< int... digit >
auto operator<<(
    std::ostream& stream,
    const std::tuple< std::integral_constant< int, digit >... >&
    )
    -> std::ostream&
{
    int digits[] = { digit... };
    std::reverse( std::begin( digits ), std::end( digits ) );
    for( int x : digits )
    {
        stream << "0123456789ABCDEF"[x];
    }
    return stream;
}

auto main() -> int
{
    std::cout << Hex_<123456>() << "\n";
}
#包括//标准::开始,标准::结束 #包括 #包括 #包括//标准::积分常数 名称空间详细信息{ 使用std::tuple; 使用std::tuple_cat; 使用std::积分_常数; 模板<无符号x,整数n\u位> 结构十六进制元组_ { 使用Type=decltype(元组)( typename十六进制元组>2*n\u位),n\u位/2>::Type() ) ); }; 模板 结构十六进制元组 { 使用Type=tuple>; }; }//名称空间详细信息 模板 使用十六进制=typename细节::十六进制元组::Type; 模板 自动操作员& ) ->std::ostream& { 整数位数[]={digit…}; 标准::反向(标准::开始(数字),标准::结束(数字)); 用于(整数x:位数) { 流整型 {
std::cout构建基
B
数字的一般问题 表示编译器时给定的无符号整数 有趣。通过应用有价值的 构建编译器时间
std::array
的技术 至少

下面定义的函数模板
digits
返回编译时间 包含基
base
数字的
char
的以null结尾的
std::array
表示合理范围[2,36]内的
Base
的整数
N
(数字“0-9A-Z”)


(gcc 4.9.2/clang 3.5.1,-std=c++14。对c++11的适应性很差)

你的意思是,获取十六进制数字的字符串吗?这是可能的。我只想计算十六进制值,并将其存储在适合元编程的某种表示形式中。我还制作了另一个程序,在其中进行了二进制转换,但我看不出这对我有什么帮助。(我在结构中使用了枚举来保存值。)我喜欢你的解决方案,但我看不出数字包是如何用正确的值(0到F)生成的。你能解释更多关于typename十六进制的信息吗?假设我想让它更通用,并为我能想象的每个基重写它。我还能用这种方法吗@Cheers@Daemonstool:十六进制(您要求的)是一种非常特殊的情况。您通常希望n字节的值为2n个十六进制数字,而不考虑该值的大小(假设为8位字节)。并且您希望对负值进行特殊处理,作为2的补码(通常)对于一般的转换到指定的任意基,你只需要足够的数字来表示值,而对于负值V,你需要的是V的数字,而不是一个补码。而且,与十六进制的不同:C++有一个内置的操作符<代码> siZeof 来告诉你数字的数目(在上面的代码中使用)。,但对于一个任意的基地来说,这是不存在的。
#include <type_traits>
#include <array>

// Get the number of base `base` digits in `n`
constexpr std::size_t base_digits(unsigned long n, unsigned base) 
{
    return (n / base) == 0 ? 1 : 1 + base_digits(n / base,base);
}

// Convert the remainder `r` of division by some base to a based digit
constexpr char based_digit(unsigned r)
{
    return r > 36 ? '!' : r < 10 ? '0' + r : 'A' + r - 10;
}

template <unsigned long N, unsigned Base, 
    std::size_t Len = base_digits(N,Base) + 1, unsigned ...Rems>
constexpr std::array<char, Len> 
digits(std::enable_if_t<(Base > 1 && Base <= 36 && N < Base)> * = nullptr)
{
    return std::array<char,Len>{{based_digit(N), Rems...,0}};
}

template <unsigned long N, unsigned Base, 
    std::size_t Len = base_digits(N,Base) + 1, unsigned ...Rems>
constexpr std::array<char,Len> 
digits(std::enable_if_t<(Base > 1 && Base <= 36 && N >= Base)> * = nullptr)
{
    return digits<N / Base, Base, Len, based_digit(N % Base), Rems...>();  
}
constexpr auto decimal = digits<9876543210,10>();
constexpr auto hex = digits<9876543210,16>();
constexpr auto octal = digits<123456789,8>();
constexpr auto binary = digits<123456789,2>();
constexpr auto b_36 = digits<36 + 35,36>();

static_assert(decimal.size() == 11,"");

#include <iostream>
#include <cassert>

int main() {
    char * pend;    
    assert(std::strtoul(decimal.data(),&pend,10) == 9876543210); 
    std::cout << decimal.data() << std::endl;
    assert(std::strtoul(hex.data(),&pend,16) == 9876543210);
    std::cout << hex.data() << std::endl;
    assert(std::strtoul(octal.data(),&pend,8) == 123456789);
    std::cout << octal.data() << std::endl;
    assert(std::strtoul(binary.data(),&pend,2) == 123456789);
    std::cout << binary.data() << std::endl;
    assert(std::strtoul(b_36.data(),&pend,36) == 36 + 35);
    std::cout << b_36.data() << std::endl;
    return 0;
}
9876543210
24CB016EA
726746425
111010110111100110100010101
1Z