首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用最短的代码返回constexpr?

如何用最短的代码返回constexpr?
EN

Stack Overflow用户
提问于 2017-08-09 17:33:29
回答 1查看 144关注 0票数 2

我使用以下代码来实现类似于C#中的类型查询:

代码语言:javascript
复制
template<class T>
constexpr bool IsSixtyFourBit() {
    return is_same<T, int64_t>() || is_same<T, uint64_t>();
}

template<class T>
constexpr bool IsDouble() {
    return is_same<T, double>() || is_same<T, double_t>();
}

template<class T>
constexpr bool IsFloat() {
    return is_same<T, float>() || is_same<T, float_t>();
}


template<class T>
constexpr bool IsReal() {
    return IsDouble<T>() || IsFloat<T>();
}

template <class T>
constexpr T MakePseudoNumberGenerator(T min, T max) {
    if constexpr (IsSixtyFourBit<T>()) {
        mt19937_64 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_int_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    } else if constexpr (IsReal<T>()) {
        mt19937_64 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_real_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    } else {
        mt19937 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_int_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    }
}

但是我不知道如何在C++17下使用最少的code...partial专门化为C++环境重写它,这应该是可行的,但它并不实用。

完整代码:https://godbolt.org/g/QBs92V

EN

回答 1

Stack Overflow用户

发布于 2017-08-09 18:15:04

在我的理解中,模拟if constexpr的方法是使用std::tuple,这种方法需要最少的额外机制和语法更改。一般的方法是翻译代码。

代码语言:javascript
复制
if constexpr (P) {
    T;
} else {
    F;
}

调用封装了true和false分支的两个多态lambdas之一:

代码语言:javascript
复制
std::get<P ? 0 : 1>(std::forward_as_tuple(
    [&](auto) { T; },
    [&](auto) { F; }))(0);

这允许将谓词和两个分支保持在相同的顺序和相同的封闭作用域中;实际上,可以将仿真代码放在检查__cplusplus版本的宏中,同时保持业务逻辑不变。

由于lambda是多态的,因此将检查它们的语法正确性,并且仅在评估P之后才会实例化。

例如,在您的示例中:

代码语言:javascript
复制
template <class T>
constexpr T MakePseudoNumberGenerator(T min, T max) {
    return std::get<IsSixtyFourBit<T>() ? 0 : 1>(std::forward_as_tuple(
    [&](auto) {
        mt19937_64 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_int_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    }, std::get<IsReal<T>() ? 0 : 1>(std::forward_as_tuple(
    [&](auto) {
        mt19937_64 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_real_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    },
    [&](auto) {
        mt19937 rng(random_device{}());            // random-number engine used (Mersenne-Twister in this case)
        uniform_int_distribution<T> uni(min, max); // guaranteed unbiased

        return uni(rng);
    }))))(0);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45586847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档