获取 sizeof(promoted(x)) 的标准方法

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

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

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.);

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

同样,我认为您不能同时处理整数和浮点数,因为我们在这里应用的 "promotion" 具有不同的含义。

我们可以简单地声明具有适当类型的重载 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)>)