在C++中,如何在编译时确定两个向量是否具有相同的长度?

kokeuurv  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(142)

Let's say I have the following code:

// A function that modifies the values in the 2 vectors
// But it needs the 2 vectors to have the same length
void compute(std::vector<int> &prev_state, std::vector<int> &curr_state);

int main() {
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {4, 5};

    a.push_back(3);
    b.push_back(6);
    b.push_back(7);

    for (int i = 0; i < 1000000; i++) {
        compute(a, b);
    }
}

I would like to determine at compile time if when I call compute , the 2 vectors have the same length. For example, the following code should fail at compile time:

// A function that modifies the values in the 2 vectors
// But it needs the 2 vectors to have the same length
void compute(std::vector<int> &prev_state, std::vector<int> &curr_state);

int main() {
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {4, 5};

    a.push_back(3);
    b.push_back(6);

    for (int i = 0; i < 1000000; i++) {
        // THIS SHOULD FAIL AT COMPILE TIME BECAUSE a.size() IS 4 AND b.size() IS 5
        compute(a, b);
    }
}

I know there is at least a runtime solution for this: adding an if condition that checks the sizes of the vectors. But, if I call the compute times a lot, that might cost me performance.
I know there's a solution with std::array instead of std::vector :

// A function that modifies the values in the 2 vectors
// But it needs the 2 vectors to have the same length
template <size_t N>
void compute(std::array<int, N> &prev_state, std::array<int, N> &curr_state);

int main() {
    std::array<int, 64> a = {1, 2, 3};
    std::array<int, 64> b = {4, 5};

    for (int i = 0; i < 1000000; i++) {
        compute(a, b);
    }
}

But this is too restrictive, as you have to establish the array's length at initialization. And it would generate a different function for every array length for which the function is called. I don't want this. I just want the compiler to check that the lengths are equal when I call compute.
I understand that from just using a std::vector it's impossible because there are ways to modify the vector such that we don't know the length at runtime. But we might still be able to determine that 2 vectors have the same length. For example:

int main() {
    // Here, we know a.size() is 3
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {4, 5, 6, 7};
    int n;

    std::cin >> n;
    while(n--) {
        a.push_back(n);
        b.push_back(n);
    }
    b.pop();

    // Here, a and b have both length n + 3
    // I would like the compiler to determine that they have the same length
    // Even if it doesn't know n
}

I understand that it's a hard problem for the compiler to determine the size of the vector. At least, I want to know is if there are any type hints or features that C++ has that limits the operations that we can do on a vector, such that its length can be determined at compile time.
Tl;DR My questions are:

  1. Given a vector, after applying some operations on it, can the compiler determine its length?
  2. If not, is there a way to limit the operations on the vector such that the compiler can determine its length?
  3. Can the compiler determine if 2 vectors have the same length?
  4. Does C++ have any compile time features that can help us check if a relation between two objects holds?
vc9ivgsu

vc9ivgsu1#

Use a single vector.

struct states_type
{
   int prev;
   int curr;
};

void compute(std::vector<states_type> &states);

int main() {
    std::vector<states_type> a;

    a.push_back({1,4});
    a.push_back({2,5});
    a.push_back({3,6});

    for (int i = 0; i < 1000000; i++) {
        compute(a);
    }
}

相关问题