内联函数,它等于“sizeof expression”,但返回一个有符号值

时间:2017-12-12 16:12:25

标签: c++

是否可以围绕“sizeof expression”创建一个内联函数包装器,它返回一个带符号的数字?

包装函数如何显示?它应该适用于所有类型的表达式(C数组等),因此它可以是sizeof的一对一替换,但它返回一个带符号的数字。

所以,基本上,我想要一个ssizeof,它会返回一个有符号的数字,如下所示:

constexpr std::ptrdiff_t ssizeof(X) {
    return static_cast<std::ptrdiff_t>(sizeof(X));
}

例如:

long a;
int b = 8;

// no signed/unsigned comparison warning here, because
// ssizeof(a) returns a signed number
if (ssizeof(a)<b) {
}

解决方案可能不那么简单,因为自动数组 - >指针衰减规则(可能还有其他问题?)。

如果无法进行一对一替换(因为ssizeof的参数将始终被评估),如果允许评估,是否可以这样做?

2 个答案:

答案 0 :(得分:1)

为了帮助您入门,您可以使用模板:

#include <iostream>

template <typename T>
constexpr std::ptrdiff_t ssizeof(T&& expression = {})
{
    return static_cast<std::ptrdiff_t>(sizeof(T));
}

int main()
{
    {
        int a[10];

        std::cout << "ssizeof<int>() = " << ssizeof<int>() << std::endl;
        std::cout << "ssizeof<int[3]>() = " << ssizeof<int[3]>() << std::endl;
        std::cout << "ssizeof<int[3]>() = " << ssizeof(a) << " / " << (sizeof a) << std::endl;
    }

    {
        int a;
        int b = 4;

        std::cout << "ssizeof<int[3]>() = " << ssizeof(a) << " / " << sizeof(a) << std::endl;
    }

    std::cout << "Done...";

    std::getchar();

    return EXIT_SUCCESS;
}

答案 1 :(得分:1)

当然有很多方法可以做到,但是我已经决定了以下几点:

using ssize_t = std::make_signed_t<size_t>;

template <size_t usize> static inline constexpr ssize_t ssizeof_impl() {
  static_assert(usize <= std::numeric_limits<ssize_t>::max());
  return static_cast<ssize_t>(usize);
}

#define ssizeof(type_or_expr) (ssizeof_impl<sizeof(type_or_expr)>())

它使用预处理器宏来完成所需工作的绝对最小限度,其余工作由constexpr函数完成。

然后,您使用ssizeof的方式与使用sizeof的方式完全相同,并且它可以完成预期的工作-没有未定义的行为。