<legend id='BgrRt'><style id='BgrRt'><dir id='BgrRt'><q id='BgrRt'></q></dir></style></legend>
  1. <i id='BgrRt'><tr id='BgrRt'><dt id='BgrRt'><q id='BgrRt'><span id='BgrRt'><b id='BgrRt'><form id='BgrRt'><ins id='BgrRt'></ins><ul id='BgrRt'></ul><sub id='BgrRt'></sub></form><legend id='BgrRt'></legend><bdo id='BgrRt'><pre id='BgrRt'><center id='BgrRt'></center></pre></bdo></b><th id='BgrRt'></th></span></q></dt></tr></i><div id='BgrRt'><tfoot id='BgrRt'></tfoot><dl id='BgrRt'><fieldset id='BgrRt'></fieldset></dl></div>

    <small id='BgrRt'></small><noframes id='BgrRt'>

  2. <tfoot id='BgrRt'></tfoot>

      • <bdo id='BgrRt'></bdo><ul id='BgrRt'></ul>
    1. C++ 中的 long long int 与 long int 与 int64_t

      时间:2023-09-19
      <i id='stxAx'><tr id='stxAx'><dt id='stxAx'><q id='stxAx'><span id='stxAx'><b id='stxAx'><form id='stxAx'><ins id='stxAx'></ins><ul id='stxAx'></ul><sub id='stxAx'></sub></form><legend id='stxAx'></legend><bdo id='stxAx'><pre id='stxAx'><center id='stxAx'></center></pre></bdo></b><th id='stxAx'></th></span></q></dt></tr></i><div id='stxAx'><tfoot id='stxAx'></tfoot><dl id='stxAx'><fieldset id='stxAx'></fieldset></dl></div>
    2. <legend id='stxAx'><style id='stxAx'><dir id='stxAx'><q id='stxAx'></q></dir></style></legend>
        <tbody id='stxAx'></tbody>
    3. <tfoot id='stxAx'></tfoot>

          <bdo id='stxAx'></bdo><ul id='stxAx'></ul>

          <small id='stxAx'></small><noframes id='stxAx'>

              1. 本文介绍了C++ 中的 long long int 与 long int 与 int64_t的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                我在使用 C++ 类型特征时遇到了一些奇怪的行为,并将我的问题缩小到这个古怪的小问题,我将对此进行大量解释,因为我不想留下任何误解.

                I experienced some odd behavior while using C++ type traits and have narrowed my problem down to this quirky little problem for which I will give a ton of explanation since I do not want to leave anything open for misinterpretation.

                假设你有一个这样的程序:

                Say you have a program like so:

                #include <iostream>
                #include <cstdint>
                
                template <typename T>
                bool is_int64() { return false; }
                
                template <>
                bool is_int64<int64_t>() { return true; }
                
                int main()
                {
                 std::cout << "int:	" << is_int64<int>() << std::endl;
                 std::cout << "int64_t:	" << is_int64<int64_t>() << std::endl;
                 std::cout << "long int:	" << is_int64<long int>() << std::endl;
                 std::cout << "long long int:	" << is_int64<long long int>() << std::endl;
                
                 return 0;
                }
                

                在使用 GCC(以及使用 32 位和 64 位 MSVC)的 32 位编译中,程序的输出将是:

                In both 32-bit compile with GCC (and with 32- and 64-bit MSVC), the output of the program will be:

                int:           0
                int64_t:       1
                long int:      0
                long long int: 1
                

                但是,64 位 GCC 编译产生的程序将输出:

                However, the program resulting from a 64-bit GCC compile will output:

                int:           0
                int64_t:       1
                long int:      1
                long long int: 0
                

                这很奇怪,因为 long long int 是一个有符号的 64 位整数,并且就所有意图和目的而言,与 long int 相同int64_t 类型,因此逻辑上,int64_tlong intlong long int 将是等效类型 - 使用这些时生成的程序集类型相同.一看 stdint.h 就会告诉我原因:

                This is curious, since long long int is a signed 64-bit integer and is, for all intents and purposes, identical to the long int and int64_t types, so logically, int64_t, long int and long long int would be equivalent types - the assembly generated when using these types is identical. One look at stdint.h tells me why:

                # if __WORDSIZE == 64
                typedef long int  int64_t;
                # else
                __extension__
                typedef long long int  int64_t;
                # endif
                

                在 64 位编译中,int64_tlong int,而不是 long long int(显然).

                In a 64-bit compile, int64_t is long int, not a long long int (obviously).

                解决这种情况非常简单:

                The fix for this situation is pretty easy:

                #if defined(__GNUC__) && (__WORDSIZE == 64)
                template <>
                bool is_int64<long long int>() { return true; }
                #endif
                

                但这是非常骇人听闻的,并且不能很好地扩展(实体的实际功能,uint64_t 等).所以我的问题是: 有没有办法告诉编译器一个 long long int 也是一个 int64_t,就像 long int 是?

                But this is horribly hackish and does not scale well (actual functions of substance, uint64_t, etc). So my question is: Is there a way to tell the compiler that a long long int is the also a int64_t, just like long int is?

                我最初的想法是这是不可能的,因为 C/C++ 类型定义的工作方式.没有一种方法可以为编译器指定基本数据类型的类型等效性,因为这是编译器的工作(并且允许这样做可能会破坏很多事情)并且 typedef 只能以一种方式进行.

                My initial thoughts are that this is not possible, due to the way C/C++ type definitions work. There is not a way to specify type equivalence of the basic data types to the compiler, since that is the compiler's job (and allowing that could break a lot of things) and typedef only goes one way.

                我也不太在意在这里得到答案,因为这是一个超级骗子的边缘案例,我不怀疑任何人会在示例不是精心设计的时候关心(这是否意味着这应该是社区维基?).

                I'm also not too concerned with getting an answer here, since this is a super-duper edge case that I do not suspect anyone will ever care about when the examples are not horribly contrived (does that mean this should be community wiki?).

                Append:我使用部分模板特化而不是更简单的例子的原因:

                Append: The reason why I'm using partial template specialization instead of an easier example like:

                void go(int64_t) { }
                
                int main()
                {
                    long long int x = 2;
                    go(x);
                    return 0;
                }
                

                那个例子仍然可以编译,因为 long long int 可以隐式转换为 int64_t.

                is that said example will still compile, since long long int is implicitly convertible to an int64_t.

                Append:目前唯一的答案是假设我想知道类型是否为 64 位.我不想误导人们认为我关心这个问题,并且可能应该提供更多关于这个问题表现出来的例子.

                Append: The only answer so far assumes that I want to know if a type is 64-bits. I did not want to mislead people into thinking that I care about that and probably should have provided more examples of where this problem manifests itself.

                template <typename T>
                struct some_type_trait : boost::false_type { };
                
                template <>
                struct some_type_trait<int64_t> : boost::true_type { };
                

                在这个例子中,some_type_trait 将是一个 boost::true_type,但 some_type_trait 不会是.虽然这在 C++ 的类型概念中是有道理的,但并不可取.

                In this example, some_type_trait<long int> will be a boost::true_type, but some_type_trait<long long int> will not be. While this makes sense in C++'s idea of types, it is not desirable.

                另一个例子是使用像 same_type 这样的限定符(这在 C++0x 概念中很常见):

                Another example is using a qualifier like same_type (which is pretty common to use in C++0x Concepts):

                template <typename T>
                void same_type(T, T) { }
                
                void foo()
                {
                    long int x;
                    long long int y;
                    same_type(x, y);
                }
                

                该示例无法编译,因为 C++(正确地)看到类型不同.g++ 将无法编译并出现如下错误:没有匹配的函数调用 same_type(long int&, long long int&).

                That example fails to compile, since C++ (correctly) sees that the types are different. g++ will fail to compile with an error like: no matching function call same_type(long int&, long long int&).

                我想强调的是,我理解为什么会发生这种情况,但我正在寻找一种不会强迫我到处重复代码的解决方法.

                I would like to stress that I understand why this is happening, but I am looking for a workaround that does not force me to repeat code all over the place.

                推荐答案

                您无需转到 64 位即可看到此类内容.在常见的 32 位平台上考虑 int32_t.它可能是 typedefintlong,但显然一次只能是两者之一.intlong 当然是不同的类型.

                You don't need to go to 64-bit to see something like this. Consider int32_t on common 32-bit platforms. It might be typedef'ed as int or as a long, but obviously only one of the two at a time. int and long are of course distinct types.

                不难看出,在 32 位系统上没有使 int == int32_t == long 的变通方法.出于同样的原因,在 64 位系统上没有办法使 long == int64_t == long long.

                It's not hard to see that there is no workaround which makes int == int32_t == long on 32-bit systems. For the same reason, there's no way to make long == int64_t == long long on 64-bit systems.

                如果可以,对于重载 foo(int)foo(long)foo(long long) 的代码,可能的后果将是相当痛苦的 - 突然他们对同一个重载有两个定义?!

                If you could, the possible consequences would be rather painful for code that overloaded foo(int), foo(long) and foo(long long) - suddenly they'd have two definitions for the same overload?!

                正确的解决方案是你的模板代码通常不应该依赖于一个精确的类型,而应该依赖于该类型的属性.对于特定情况,整个 same_type 逻辑仍然可以:

                The correct solution is that your template code usually should not be relying on a precise type, but on the properties of that type. The whole same_type logic could still be OK for specific cases:

                long foo(long x);
                std::tr1::disable_if(same_type(int64_t, long), int64_t)::type foo(int64_t);
                

                即,重载 foo(int64_t)完全foo(long) 相同时未定义.

                I.e., the overload foo(int64_t) is not defined when it's exactly the same as foo(long).

                使用 C++11,我们现在有一个标准的方法来写这个:

                [edit] With C++11, we now have a standard way to write this:

                long foo(long x);
                std::enable_if<!std::is_same<int64_t, long>::value, int64_t>::type foo(int64_t);
                

                或 C++20

                long foo(long x);
                int64_t foo(int64_t) requires (!std::is_same_v<int64_t, long>);
                

                这篇关于C++ 中的 long long int 与 long int 与 int64_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:在 GCC/G++ 编译器中使用 -pedantic 的目的是什么? 下一篇:GCC 中的函数静态变量是线程安全的吗?

                相关文章

                最新文章

                      <bdo id='rYdl2'></bdo><ul id='rYdl2'></ul>
                    <i id='rYdl2'><tr id='rYdl2'><dt id='rYdl2'><q id='rYdl2'><span id='rYdl2'><b id='rYdl2'><form id='rYdl2'><ins id='rYdl2'></ins><ul id='rYdl2'></ul><sub id='rYdl2'></sub></form><legend id='rYdl2'></legend><bdo id='rYdl2'><pre id='rYdl2'><center id='rYdl2'></center></pre></bdo></b><th id='rYdl2'></th></span></q></dt></tr></i><div id='rYdl2'><tfoot id='rYdl2'></tfoot><dl id='rYdl2'><fieldset id='rYdl2'></fieldset></dl></div>

                    <tfoot id='rYdl2'></tfoot>

                    <small id='rYdl2'></small><noframes id='rYdl2'>

                  1. <legend id='rYdl2'><style id='rYdl2'><dir id='rYdl2'><q id='rYdl2'></q></dir></style></legend>