获得sizeof(提升(x))的标准方法

The standard way to get sizeof(promoted(x))

本文关键字:标准 方法 sizeof 提升 获得      更新时间:2023-10-16

是否有一种标准方法来获取变量作为可变参数传递时将提升到的类型的大小?

auto x = ...;
auto y = sizeof(promoted(x));

结果应该是:

char  -> sizeof(int)
int   -> sizeof(int)
float -> sizeof(double)
...
auto s = sizeof(+x);

应该能处理整数。

+x使用一元+运算符,它像其他算术运算符一样进行整数提升。

我不知道float的任何标准提升规则适用于这里(在整数提升意义上),因为您可以在不提升的情况下使用它们进行算术。如果您总是希望至少提升到double,您可以尝试

auto s = sizeof(x + 0.);

,然后在到达之前区分浮点数和整数。

同样,我不认为你可以同时处理整数和浮点数,因为我们在这里应用的"提升"的含义不同。

可以简单地用适当的类型声明重载的promoted函数:

int promoted(char);
int promoted(short);
int promoted(int);
long promoted(long);
long long promoted(long long);
double promoted(float);
double promoted(double);
long double promoted(long double);

注意这些函数不需要实现,因为我们从来没有真正调用过它们。

下面是一个简单的测试运行,在我的机器上打印1,4和4,8:
std::cout << sizeof('a') << 'n';
std::cout << sizeof(promoted('a')) << 'n';
std::cout << sizeof(3.14f) << 'n';
std::cout << sizeof(promoted(3.14f)) << 'n';

为了概括Baum mit Augen的答案,您可以这样编写函数模板:

template <typename T>
auto promoted(T) 
  -> std::enable_if_t<std::is_integral<T>::value, decltype(+T{})>;
template <typename T>
auto promoted(T) 
  -> std::enable_if_t<std::is_floating_point<T>::value, decltype(T{}+0.)>;
//usage
sizeof(promoted(a))

或者使用类型特征的版本:

template <typename T, typename = void>
struct promoted;
template <typename T>
struct promoted<T, std::enable_if_t<std::is_integral<T>::value>>
{ using type = decltype(+T{}); };
template <typename T>
struct promoted<T, std::enable_if_t<std::is_floating_point<T>::value>>
{ using type = decltype(T{} + 0.); };
template <typename T>
using promoted_t = typename promoted<T>::type;
//usage
sizeof(promoted_t<decltype(a)>)