Slices in Cilk
#include <cilk/cilk.h>
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Unlike arrays, vectors in C++ are dynamically sized.
// An uninitialized vector has size 0.
std::vector<std::string> s;
std::cout << "uninit: " << (s.empty() ? "true" : "false") << " " << (s.size() == 0 ? "true" : "false") << std::endl;
// To create an empty vector with non-zero size, we can use the constructor.
s = std::vector<std::string>(3);
std::cout << "emp: [";
for (const auto& elem : s) std::cout << elem << " ";
std::cout << "] len: " << s.size() << " cap: " << s.capacity() << std::endl;
// We can set and get just like with arrays.
s[0] = "a";
s[1] = "b";
s[2] = "c";
std::cout << "set: [";
for (const auto& elem : s) std::cout << elem << " ";
std::cout << "]" << std::endl;
std::cout << "get: " << s[2] << std::endl;
// size() returns the length of the vector as expected.
std::cout << "len: " << s.size() << std::endl;
// We can use push_back to append elements to a vector.
s.push_back("d");
s.push_back("e");
s.push_back("f");
std::cout << "apd: [";
for (const auto& elem : s) std::cout << elem << " ";
std::cout << "]" << std::endl;
// Vectors can be copied using the assignment operator.
std::vector<std::string> c = s;
std::cout << "cpy: [";
for (const auto& elem : c) std::cout << elem << " ";
std::cout << "]" << std::endl;
// We can use iterators to get a slice of the vector.
auto l = std::vector<std::string>(s.begin() + 2, s.begin() + 5);
std::cout << "sl1: [";
for (const auto& elem : l) std::cout << elem << " ";
std::cout << "]" << std::endl;
// This gets a slice up to (but excluding) the 5th element.
l = std::vector<std::string>(s.begin(), s.begin() + 5);
std::cout << "sl2: [";
for (const auto& elem : l) std::cout << elem << " ";
std::cout << "]" << std::endl;
// And this gets a slice from (and including) the 3rd element.
l = std::vector<std::string>(s.begin() + 2, s.end());
std::cout << "sl3: [";
for (const auto& elem : l) std::cout << elem << " ";
std::cout << "]" << std::endl;
// We can declare and initialize a vector in a single line as well.
std::vector<std::string> t = {"g", "h", "i"};
std::cout << "dcl: [";
for (const auto& elem : t) std::cout << elem << " ";
std::cout << "]" << std::endl;
// The C++ standard library contains a number of useful utility functions for vectors.
std::vector<std::string> t2 = {"g", "h", "i"};
if (t == t2) {
std::cout << "t == t2" << std::endl;
}
// Vectors can be composed into multi-dimensional data structures.
std::vector<std::vector<int>> twoD(3);
for (int i = 0; i < 3; i++) {
int innerLen = i + 1;
twoD[i] = std::vector<int>(innerLen);
for (int j = 0; j < innerLen; j++) {
twoD[i][j] = i + j;
}
}
std::cout << "2d: [";
for (const auto& row : twoD) {
std::cout << "[";
for (const auto& elem : row) std::cout << elem << " ";
std::cout << "] ";
}
std::cout << "]" << std::endl;
return 0;
}
This Cilk code demonstrates the equivalent concepts of slices in C++ using vectors. Here are some key points:
We use
std::vector
as the equivalent of slices in Go. Vectors in C++ are dynamically sized containers.Instead of
append
, we use thepush_back
method to add elements to the end of a vector.Slicing in C++ is typically done using iterators. We create new vectors from ranges of existing vectors to demonstrate slicing.
The
cilk::cilk
header is included for Cilk-specific features, although this example doesn’t explicitly use any Cilk parallelism.We use range-based for loops to print vector contents, which is more idiomatic in C++.
The
slices.Equal
function from Go is replaced with the==
operator, which works for vectors of comparable types in C++.Multi-dimensional vectors are created as vectors of vectors.
This code maintains the structure and explanations of the original Go example while adapting it to C++ and Cilk conventions.