用于比较类型的字节大小的编译器宏

Compiler macro to compare byte size of types

这个if-statement可以用#if ....宏代替吗?
可能不必包含(太多)额外的 headers.

#include <cstdint>
#include <string>
///Parse a string to obtain a fixed width type
inline uint64_t stou64(const std::string& in) {
    if (sizeof(unsigned long) == sizeof(uint64_t)) {
        return std::stoul(in);
    } else {
        return std::stoull(in);
    }
}

您不需要 pre-processor 宏。无论大小如何,函数都是 well-defined,编译器足够聪明,可以完全优化未使用的分支。

如果您想确保在禁用优化的情况下也删除未使用的分支,您可以使用if constexpr。在您的示例中,只需在 if 之后添加 constexpr


如果您不需要支持当前活动的语言环境,请考虑改用 std::from_chars

不,您的 if 语句不同,因为 if 和 else 路径都经过编译并且必须是有效的表达式,即使编译器随后将代码优化为仅采用的路径。在 #if 宏中,编译器只看到剩下的部分。删除的部分不必对给定的论点有意义。

由于这可能是模板的问题,因此在 c++17 中添加了 constexpr if 语法。

#include <cstdint>
#include <string>
///Parse a string to obtain a fixed width type
inline uint64_t stou64(const std::string& in) {
    if constexpr (sizeof(unsigned long) == sizeof(uint64_t)) {
        return std::stoul(in);
    } else {
        return std::stoull(in);
    }
}

注意:在这个具体的例子中它并不重要。但为什么不习惯 if constexpr 呢?

我更喜欢这种方法(在 C++17 之前std::from_chars):

template<typename T>
T string_to(const std::string& in);

template<>
int string_to<int>(const std::string& in) {
    return std::stoi(in);
}

template<>
unsigned string_to<unsigned>(const std::string& in) {
    return std::stol(in);
}

template<>
long string_to<long>(const std::string& in) {
    return std::stol(in);
}

template<>
long long string_to<long long>(const std::string& in) {
    return std::stoll(in);
}

template<>
unsigned long string_to<unsigned long>(const std::string& in) {
    return std::stoul(in);
}

template<>
unsigned long long string_to<unsigned long long>(const std::string& in) {
    return std::stoull(in);
}

inline uint64_t stou64(const std::string& in) {
    return string_to<uint64_t>(in);
}

https://godbolt.org/z/T57cbq91z