C++ 变量模板解包中达到终止功能时出现异常

C++ 变量模板解包中达到终止功能时出现异常,c++,c++11,variadic-templates,constexpr,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,ar

因此,我正在使用模板&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;
}
模板
constexpr T get_参数(大小索引)
{
返回T();
};
模板
constexpr T get_参数(大小索引)
{
返回索引?get_参数(索引-1):arg;
}
此处的终止函数当前是一个伪占位符。所以这个函数可以工作,但是如果超出范围,返回一个0,我希望它做的是崩溃…但是它需要两种模式的失败。get_参数可以在编译时调用,在编译时我希望索引超出范围,从而导致编译器错误。或者它可以在运行时调用,我希望它抛出一个运行时错误

我也有以下选择:

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;
}
模板
constexpr T get_参数(大小索引)
{
返回false?T():抛出std::超出参数范围(“索引超出参数范围”);
}
模板
constexpr T get_参数(大小索引)
{
回报指数?
(count_args()?
get_参数(索引-1):
抛出std::超出参数范围(“索引超出参数范围”):
精氨酸;
}
但是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")) :
test.hpp:32:69:错误:表达式“”不是常量表达式
抛出std::超出参数范围(“索引超出参数范围”):
有人有更好的方法吗?

以下内容可能会有所帮助(只有一项检查):

模板
constexpr std::数组getArray()
{
返回{Ts..};
}
模板
constexpr T get_参数(大小索引)
{
返回索引
C++14可能会有所帮助,可能会有几个语句,如:

  • 局部变量(不需要此
    常量转换
  • assert
    (除了可能的
    throw

您是否考虑过返回指针(超出范围时为null)?@MatthieuM。在有效的情况下,它会指向什么?Args仅作为模板参数存在…啊,对了,不幸的是没有
std::选项
。。。我想你可以自己包装它(用一个布尔值和默认值
T
创建你自己的简单
选项
)。有趣的解决方案…为什么需要const_cast?临时数组不是const,而
操作符[]
只是const对象的constepr。啊,这很有意义(I+1,因为是的)。下一个问题:如果在运行时调用此函数,我的方法可以递归内联(如果编译器支持),这(可能,如果编译器有魔力)可以减少为常量值返回…此修复程序是否必须为std::数组进行堆分配?(我可能只需要检查程序集就可以得到这个答案,但如果你头脑清楚这一点,那就太酷了)(如果T没有默认构造函数,这也解决了问题)
array::operator[]
在C++11中不是
constexpr
。令人惊讶的是,代码实际上更简单。
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");;
}