调用constexpr函数的给定重载时触发编译时错误

问题描述 投票:1回答:1

我正在编写自定义变量模板,在编译时映射中执行查找。

问题是,我想在每次在该映射中找不到值时触发编译时错误 - 最好带有描述性错误消息。

示例代码:

template<key_t k, class pair, class... pairs>
static constexpr value_t get_local(std::tuple<pair, pairs...>)
{
    return (pair::key == k) ? pair::value : get_local<k>(std::tuple<pairs...>{});
}

template<key_t k> static constexpr value_t get_local(std::tuple<>)
{
    // Trigger error!
}

我可以在代码的第二部分中保留get_local undefined,它实际上会触发链接器错误,但这不属于“描述性错误消息”的类别。

我认为,静态断言在这里毫无用处。

我正在使用C ++ 17

c++ compiler-errors c++17 constexpr
1个回答
1
投票

并立即下降的解决方案是delete超载:

template<key_t k> static constexpr value_t get_local(std::tuple<>) = delete;

这将提供一些描述性消息,我们尝试使用不存在的基本案例。

或者,使用静态断言:

template<key_t k> struct always_false { static constexpr bool value = false; };

template<key_t k> static constexpr value_t get_local(std::tuple<>)
{
    static_assert(always_false<k>::value, "Hit bad case!");
    return std::declval<value_t>();
}

需要always_false实用程序来使断言条件依赖,因此模板不是格式错误;没有诊断要求,因为static_assert(false, ...)会成功。

请注意,您自己在自己的条件运算符中实例化此重载:

(pair::key == k) ? pair::value : get_local<k>(std::tuple<pairs...>{});

当你用单个元素击中元组的情况时。条件表达式的两个“分支”必须有效。使用if constepxr有条件地处理它:

if constexpr (pair::key == k) return pair::value;
else                          return get_local<k>(std::tuple<pairs...>{});

既然你确实指出pair::key == k可以用常量表达式进行评估。

© www.soinside.com 2019 - 2024. All rights reserved.