【问题标题】:How to turn a variable content constant for use it as the size of std::array?如何将变量内容常量用作 std::array 的大小?
【发布时间】:2020-04-21 15:14:32
【问题描述】:

我有一个属于该类的大小变量。我想将它用作 std::array 的大小,但我无法做到这一点。我发现了一些提到 constexpr 的文章,但到目前为止没有任何用处。你能帮帮我吗?

#include<array>
#include<iostream>

class MyClass{
private:
        int size; //variable I need to copy the content and make it constant.
        void calculateSize(int x){
                size = 2 * x;
        }

public:
        MyClass(){}

        void createArray(int val){

                calculateSize(val);
                std::cout << "the size is: " << size << std::endl;
                std::array<int, size> myArray; // error
        }
};

int main(){

        MyClass c;
        c.createArray(5);
        return 0;
}

错误:

main.cpp:在成员函数‘void MyClass::createArray(int)’中: main.cpp:20:19:错误:在常量表达式中使用“this” std::array myArray;

【问题讨论】:

  • 这就是std::vector 的用途。你为什么不为此使用std::vector
  • std::vector 是个好主意,但我也想使用其他容器。在这种情况下,我在声明之前已经提前知道了容器的大小。
  • 至于错误,即使你没有在任何地方显式使用this,它在访问成员变量时也被隐式使用:array&lt; int, this-&gt;size &gt;
  • 有许多不同的容器可用是有原因的。它们的存在不仅仅是为了使用不同的名称。它们中的每一个都有其最适合的特定优势和情况,而在其他情况下则不是最佳的。在这种情况下,std::array 不是合适的选择或选择,但std::vector 是。这就是它的用途。

标签: c++ class stdarray


【解决方案1】:

这里的问题是对常量含义的误解。在 C++ 中,std::array 的大小必须是常量,其中常量表示“大小在编译时已知”。正如您的班级所建议的那样,size 变量是在运行时计算的。同样,constexpr 关键字只能用于其值在编译时已知且永远不会改变的变量。

所以你有几个选择。

  1. 您可以使用std::vector 并使用大小对其进行初始化

    std::vector<int> vec(5); // Initializes a vector of size 5
    
  2. 如果你真的在编译时知道数组的大小,你可以使用 constexpr

    constexpr int size = 2 * 10;
    std::array<int, size> arr; // Make an array of size 20
    

【讨论】:

  • 我正在考虑你的观点。也许 std::vector::reserve() 也很有用,因为我知道向量的大小。
  • 将 5 传递给 std::vector 的构造函数的行为更接近您的要求。但是,如果您不想在向量中使用默认构造元素,那么调用保留和推送元素确实可能是更好的方法。
【解决方案2】:

这根本不可能。非静态成员变量不是编译时常量值。模板参数必须是编译时常量。因此,您不能将非静态成员变量用作std::array 的大小。

如果您想拥有一个在运行时确定大小的数组,那么您需要动态分配该数组。实现这一目标的最简单方法是使用std::vector

如果您想拥有一个恒定大小的数组,那么您可以为此目的使用编译时常量。该值不能是非静态成员变量。

【讨论】:

    【解决方案3】:

    作为替代解决方案,使用模板:

    template <int _size>
    class MyClass{
    private:
        // size calculation at compile time
        constexpr static int size = _size * 2; 
    
    public:
        // parameter removed since it's unnecessary
        void createArray(){  
            std::cout << "the size is: " << size << std::endl;
            std::array<int, size> myArray;
        }
    };
    
    int main(){
        // pass size as template argument
        MyClass<5> c;
        c.createArray();
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-03
      • 2019-12-28
      • 1970-01-01
      • 2015-01-14
      • 2012-12-05
      • 1970-01-01
      • 2017-02-17
      • 2011-02-21
      • 1970-01-01
      相关资源
      最近更新 更多