如果在可变参数模板解包中达到终止函数,则出现异常

Exception if terminating function reached in variadic template unpacking

本文关键字:函数 终止 异常 包中达 变参 参数 如果      更新时间:2023-10-16

所以我正在使用模板和constexpr,特别是可变参数模板,我做了以下功能:

template <typename T>
constexpr T get_argument(size_t index)
{
  return T();
};
template <typename T, T arg, T... args>
constexpr T get_argument(size_t index)
{
  return index ? get_argument<T,args...>(index-1) : arg;
}

此处的终止函数当前是一个虚拟占位符。所以这个函数有效,但如果超出范围,则返回 0,我希望它做的是崩溃......但它需要 2 种失败方式。get_argument可以在编译时调用,我希望索引超出范围以导致编译器错误。或者它可以在运行时调用,我希望它抛出运行时错误......

我也可以选择这个:

template <typename T>
constexpr T get_argument(size_t index)
{
  return false ? T() : throw std::out_of_range("Index out of argument range");
}
template <typename T, T arg, T... args>
constexpr T get_argument(size_t index)
{
  return index ?
        (count_args<T,args...>() ?
           get_argument<T,args...>(index-1) :
           throw std::out_of_range("Index out of argument range")) :
        arg;
}

但是 1)我不喜欢语法(总是错误的条件,加上在模糊的尝试中检查两次以使输出有意义),并且 2) 错误很混乱:

test.hpp:32:69: error: expression '<throw-expression>' is not a constant-expression
            throw std::out_of_range("Index out of argument range")) :

有人有更好的方法吗?

以下可能会有所帮助(仅进行一次检查):

template <typename T, T ... Ts>
constexpr std::array<T, sizeof...(Ts)> getArray()
{
    return {{Ts...}};
}
template <typename T, T ... Ts>
constexpr T get_argument(size_t index)
{
  return index < sizeof...(Ts) ?
    const_cast<const std::array<T, sizeof...(Ts)>&&>(getArray<T, Ts...>())[index] :
    throw std::out_of_range("Index out of argument range");;
}

C++14 可能会有所帮助,可以有几个陈述,例如:

  • 局部变量(无需此const_cast
  • assert(可能除了throw之外)。