为什么constexpr无法绕过constexpr评估?

时间:2018-12-30 13:00:39

标签: c++ c++17 constexpr if-constexpr

我正在为使用宏的类型调度构建一个静态循环。这是 我到目前为止所取得的成就。

select uid, count(*) as counter
from table
where month = 12 and year = 2018
group by uid 

还有“ godbolt”链接https://godbolt.org/z/GcMZI3

问题是,为什么前四个分支编译失败?

1 个答案:

答案 0 :(得分:4)

请勿使用宏,而应使用功能模板。 if constexpr通过根据模板的当前实例 丢弃未采用的分支来工作。

template <std::size_t n, typename F>
void loop(F&& f)
{
    static_assert(n <= 8 && "static loop size should <= 8");
    if constexpr (n >= 8)
        f(std::integral_constant<size_t, n - 8>());
    if constexpr (n >= 7)
        f(std::integral_constant<size_t, n - 7>());
    if constexpr (n >= 6)
        f(std::integral_constant<size_t, n - 6>());
    if constexpr (n >= 5)
        f(std::integral_constant<size_t, n - 5>());
    if constexpr (n >= 4)
        f(std::integral_constant<size_t, n - 4>());
    if constexpr (n >= 3)
        f(std::integral_constant<size_t, n - 3>());
    if constexpr (n >= 2)
        f(std::integral_constant<size_t, n - 2>());
    if constexpr (n >= 1)
        f(std::integral_constant<size_t, n - 1>());
}

用法:

int main() {
    constexpr auto t = std::make_tuple(1, "string", 0.2, 3);
    loop<tupleSize(t)>([&](auto i) { cout << std::get<i>(t) << endl; });
    return 0;
}

live example on godbolt.org


来自cppreference

  

如果constexpr if语句出现在模板实体内,并且实例化后条件不依赖于值,则在实例化封闭模板时不会实例化丢弃的语句。

     

在模板之外,完全检查了丢弃的语句。如果constexpr不能代替#if预处理指令