在使用C ++类型特征时,我经历了一些奇怪的行为,并且将我的问题缩小到这个古怪的小问题,由于我不想留下任何可能引起误解的信息,因此我将作大量解释。
假设您有一个像这样的程序:
#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:\t" << is_int64<int>() << std::endl;
std::cout << "int64_t:\t" << is_int64<int64_t>() << std::endl;
std::cout << "long int:\t" << is_int64<long int>() << std::endl;
std::cout << "long long int:\t" << is_int64<long long int>() << std::endl;
return 0;
}
在使用GCC(以及32位和64位MSVC)的32位编译中,程序的输出为:
int: 0
int64_t: 1
long int: 0
long long int: 1
但是,由64位GCC编译产生的程序将输出:
int: 0
int64_t: 1
long int: 1
long long int: 0
这很奇怪,因为它long long int
是一个带符号的64位整数,并且就所有意图和目的而言,都与long int
andint64_t
类型相同,因此从逻辑上讲,int64_t
,long int
并且long long int
将是等效类型-使用这些类型时生成的程序集是相同的。一看就stdint.h
告诉我为什么:
# if __WORDSIZE == 64
typedef long int int64_t;
# else
__extension__
typedef long long int int64_t;
# endif
在64位编译中,int64_t
是long int
,而不是long long int
(显然)。
解决这种情况的方法非常简单:
#if defined(__GNUC__) && (__WORDSIZE == 64)
template <>
bool is_int64<long long int>() { return true; }
#endif
但这是骇人听闻的,并且扩展性不好(实体的实际功能uint64_t
等)。 所以我的问题是:有没有办法告诉编译器along long int
也是aint64_t
,就像long int
is一样?
我最初的想法是,由于C / C ++类型定义的工作方式,这是不可能的。没有一种方法可以将基本数据类型的类型等效性指定给编译器,因为这是编译器的工作(允许这样做可能会破坏很多事情),并且typedef
只有一种方法。
我也不是很想在这里得到答案,因为这是一个超级骗局,我不怀疑任何人都不会在不妥善设计示例的情况下关心它(这是否应该是社区Wiki?) 。
附录:我之所以使用部分模板专业化,而不是像下面这样的简单示例,是因为
void go(int64_t) { }
int main()
{
long long int x = 2;
go(x);
return 0;
}
是因为上述示例仍可以编译,因为它long long int
可以隐式转换为int64_t
。
追加:到目前为止,唯一的答案是假设我想知道类型是否为64位。我不想误导人们以为我对此很在意,并且可能应该提供更多示例说明此问题的所在。
template <typename T>
struct some_type_trait : boost::false_type { };
template <>
struct some_type_trait<int64_t> : boost::true_type { };
在此示例中,some_type_trait<long int>
将为boost::true_type
,但some_type_trait<long long int>
不会。尽管这在C ++的类型概念中是有意义的,但并不理想。
另一个示例使用的是类似限定符same_type
(在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&)
。
我想强调指出,我理解为什么会这样,但是我正在寻找一种解决方法,它不会迫使我在各处重复执行代码。
sizeof
每种类型的结果是否都相同?也许编译器对待大小的long long int
区别。