c++ - 编译时通过索引访问类模板的成员

标签 c++ arrays templates template-meta-programming compile-time-constant

给定一个模板,其非类型参数决定非常量的大小 int数组成员,如何在编译时通过整数索引访问数组元素?我希望通过类模板的 getter 方法进行访问 at .

我想既然类模板必须在运行前实例化,我可以传递另一个非类型类模板的 enum前一类的成员值 at确保index的方法参数是编译时常量。

我离开了类模板deliberate_error undefined 查看其参数是否在编译时计算,并在错误消息中查看编译时结果。

template <unsigned int N>
struct compile_time_int {
    enum {num = N};
};

template <unsigned int N>
struct array_wrapper {

    int arr[N];

    template <unsigned int Ind>
    constexpr int const& at(compile_time_int<Ind> const& index) const {
        return arr[index.num];
    }
};

template <unsigned int> struct deliberate_error;

int main() {
    compile_time_int<2> cti;
    array_wrapper<3> aw;
    aw.at(cti);
    deliberate_error<cti.num> my_error1;
    deliberate_error<aw.at(cti)> my_error2;
}

aw.at(cti);没有给出错误,所以我想如果我将相同的表达式传递给 deliberate_error实例 my_error2 , 编译器将显示 arr[2] 的值在错误消息中。

my_error1导致 g++ error: aggregate 'deliberate_error<2u> my_error1' has incomplete type and cannot be defined ,

显示 cti的包装整数值 2 .所以,我想如果我通过相同的 cti反对aw的getter,然后将结果传递给my_error2 , 我可以得到 arr[2]在错误消息中。但相反,它打印:

error: the value of 'aw' is not usable in a constant expression
note: 'aw' was not declared 'constexpr'
note: in template argument for type 'unsigned int'
error: invalid type in declaration before ';'

所以,我尝试在 constexpr 之前加上至 aw的声明,但这会产生更多不受欢迎的错误。这里有什么问题,我该如何解决?

最佳答案

(请注意,据我所知, std::array std::get 已经解决了您的问题。)


主要问题是您需要您的实例 aw成为constexpr当然你需要用一些值来初始化它:

constexpr array_wrapper<3> aw = { 1, 2, 3 };

关于函数at , 你可以把它写成一个普通函数,但只需将它指定为 constexpr :

constexpr int const& at(int i) const {
    return arr[i];
}

然后,aw.at(0)可以用作常量表达式:Live Demo

这样做的好处是您可以在编译时和运行时表达式中使用此函数,分别使用静态和动态索引。


如果你真的想让它模板化,你可以把它写成一个非成员,比如 std::get<N>或作为类成员,但使用 int 类型的模板参数(或 size_t 或类似)。这简化了它的定义(你可以去掉你的 compile_time_int 类模板):

template<int Index>
constexpr int const& at() const {
    return arr[Index];
}

然后,aw.at<0>()可以用作常量表达式:Live Demo

第二种方法的优点是索引保证是静态的,所以我们可以在函数中使用它进行静态边界检查,不会增加任何性能损失。我不知道第一个版本是否可行。

关于c++ - 编译时通过索引访问类模板的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20724456/

相关文章:

c - 努力使用 calloc 和 realloc 在 C 中初始化数组

c - 我的二维数组中数字的频率无法正确输出

c++ - 使用模板的运算符重载

c++ - 使用解释为函数定义的模板化构造函数的非模板化类的实例?

c++ - 为什么错误 1400 Invalid window handle?

java数组转换?

c++ - 如何将数据传递给 glutTimerFunc?

c++ - 具有模板类的函数模板特化

c++ - 与模板类中的友元函数链接错误

c++ - 如果我使用 std :find, 在 vector 对中找到一个元素,我如何才能将 vector 中的值转换为字符串?