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

时间:2014-02-11 16:22:17

标签: c++ c++11 variadic-templates constexpr

所以我正在玩模板& 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")) :

任何人都有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

以下可能有所帮助(只有一次检查):

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之外)。