ซึ่งชื่อเมธอดบ่งชี้ว่า copy() ใช้สำหรับคัดลอกข้อมูลผ่านวิธีการต่างๆ ที่มีใน C++ STL เมธอดทั้งหมดแตกต่างกันในด้านฟังก์ชันการทำงานและพารามิเตอร์ เมธอดเหล่านี้พร้อมใช้งานในไฟล์เฮดเดอร์ <algorithm> มาดูรายละเอียดแต่ละเมธอดและฟังก์ชันการทำงานกัน
copy(start_i1, end_i1, start_i2)
เมธอดนี้ใช้คัดลอกข้อมูลจากอีเทอเรเตอร์หนึ่งไปยังอีกอีเทอเร이터หนึ่งภายในช่วงที่กำหนด โดยทั้งองค์ประกอบเริ่มต้นและสิ้นสุดของอีเทอเรเตอร์จะรวมอยู่ด้วย (inclusive) ฟังก์ชันรับอาร์กิวเมนต์ 3 ประเภท ดังนี้:
- Start_i1 – ชี้ไปที่องค์ประกอบแรกของอีเทอเรเตอร์ต้นทาง (เช่น i_1) ที่จะเริ่มคัดลอกไปยังอีเทอเรเตอร์ปลายทาง (เช่น i_2)
- End_i1 – ชี้ไปที่องค์ประกอบสุดท้ายของอีเทอเรเตอร์ต้นทาง (i_1) ที่จะคัดลอกจนถึงตำแหน่งนี้
- Start_i2 – ชี้ไปที่ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ปลายทาง (i_2) ที่จะวางองค์ประกอบที่คัดลอกมา
ค่าที่ส่งคืน – ส่งคืนอีเทอเรเตอร์ที่ชี้ไปที่ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ปลายทาง (i_2) ซึ่งเป็นตำแหน่งถัดจากองค์ประกอบสุดท้ายที่คัดลอกเสร็จ
ตัวอย่าง
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
// สร้างเวกเตอร์ v1
vector<int> vec_1 = { 10, 20, 30, 40, 50 };
// ประกาศเวกเตอร์ว่างขนาด 6
vector<int> vec_2(6);
// ใช้ copy() คัดลอก 4 องค์ประกอบแรกจาก vec_1 ไป vec_2
copy(vec_1.begin(), vec_1.begin() + 4, vec_2.begin());
// แสดงผล
cout << "Elements in vector v2 copied from v1: ";
for (int i = 0; i < 4; i++) {
cout << vec_2[i] << " ";
}
return 0;
}
ผลลัพธ์
Elements in vector v2 copied from v1: 10 20 30 40
copy_n(start_i1, total, start_i2)
เมธอดนี้ก็คัดลอกข้อมูลจากอีเทอเรเตอร์หนึ่งไปอีกอีเทอเร이터หนึ่ง เช่นกัน แต่แตกต่างตรงที่ระบุจำนวนองค์ประกอบที่ต้องการคัดลอก (total) เริ่มจากตำแหน่ง start_i1 ฟังก์ชันรับอาร์กิวเมนต์ 3 ประเภท:
- Start_i1 – ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ต้นทาง
- Total – จำนวนองค์ประกอบที่ต้องการคัดลอก (รับค่าบวกและลบได้ แต่ถ้าเป็นค่าลบจะไม่ทำงาน)
- Start_i2 – ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ปลายทาง
ค่าที่ส่งคืน – อีเทอเรเตอร์ชี้ไปที่ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ปลายทาง
ตัวอย่าง
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> vec_1 = { 10, 20, 30, 40, 50 };
vector<int> vec_2(6);
// คัดลอก 4 องค์ประกอบจาก vec_1 เริ่มต้นที่ begin()
copy_n(vec_1.begin(), 4, vec_2.begin());
cout << "Elements in vector v2 copied from v1: ";
for (int i = 0; i < 4; i++) {
cout << vec_2[i] << " ";
}
return 0;
}
ผลลัพธ์
Elements in vector v2 copied from v1: 10 20 30 40
copy_if(start_i1, end_i1, start_i2, Boolean function)
เมธอดนี้คัดลอกข้อมูลตามเงื่อนไข (predicate) ภายในช่วงที่กำหนด โดยฟังก์ชันบูลีนที่ส่งผ่านเป็นอาร์กิวเมนต์ตัวที่ 4 จะตัดสินใจว่าองค์ประกอบไหนจะถูกคัดลอก ฟังก์ชันรับอาร์กิวเมนต์ 4 ประเภท:
- Start_i1 – ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ต้นทาง
- End_i1 – ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ต้นทาง
- Start_i2 – ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ปลายทาง
- Boolean function – ฟังก์ชันที่ส่งคืน
true/falseเพื่อเป็นเงื่อนไขการคัดลอก
ค่าที่ส่งคืน – อีเทอเรเตอร์ชี้ไปที่ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ปลายทาง
ตัวอย่าง
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> vec_1 = { 10, 21, 30, 40, 57 };
vector<int> vec_2(6);
// คัดลอกเฉพาะเลขคู่จาก vec_1 ไป vec_2
copy_if(vec_1.begin(), vec_1.end(), vec_2.begin(), [](int i) { return i % 2 == 0; });
cout << "Elements in vector v2 copied from v1: ";
for (int i = 0; i < 4; i++) {
cout << vec_2[i] << " ";
}
return 0;
}
ผลลัพธ์
Elements in vector v2 copied from v1: 10 30 40 0
หมายเหตุ: ผลลัพธ์แสดงค่า 0 ต่อท้ายเพราะ vec_2 มีขนาด 6 แต่คัดลอกได้แค่ 3 ค่า (10, 30, 40) ส่วนที่เหลือเป็นค่าเริ่มต้น 0
copy_backward(start_i1, end_i1, end_i2)
เมธอดนี้คัดลอกข้อมูลในทิศทางย้อนหลัง (backward) หมายถึงการเริ่มวางข้อมูลจากตำแหน่ง end_i2 แล้วย้อนกลับไปเรื่อยๆ เหมาะสำหรับการคัดลอกทับซ้อน (overlapping ranges) ที่ต้องการรักษาลำดับข้อมูล ฟังก์ชันรับอาร์กิวเมนต์ 3 ประเภท:
- Start_i1 – ตำแหน่งเริ่มต้นของอีเทอเรเตอร์ต้นทาง
- End_i1 – ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ต้นทาง
- end_i2 – ตำแหน่งสิ้นสุดของอีเทอเรเตอร์ปลายทาง (จุดที่จะเริ่มวางข้อมูลจากท้าย)
ค่าที่ส่งคืน – อีเทอเรเตอร์ชี้ไปที่ตำแหน่งเริ่มต้นของข้อมูลที่คัดลอกเสร็จในอีเทอเรเตอร์ปลายทาง
ตัวอย่าง
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> vec_1 = { 10, 21, 30, 40, 57, 67 };
vector<int> vec_2(6);
// copy_backward คัดลอกจาก vec_1[0] ถึง vec_1[3] (4 องค์ประกอบ) วางท้ายที่ vec_2[5]
copy_backward(vec_1.begin(), vec_1.begin() + 4, vec_2.begin() + 5);
cout << "Elements in vector v2 copied from v1: ";
for (int i = 0; i < vec_2.size(); i++) {
cout << vec_2[i] << " ";
}
return 0;
}
ผลลัพธ์
Elements in vector v2 copied from v1: 0 10 21 30 40 0
คำอธิบาย: โค้ดต้นฉบับมีข้อผิดพลาดที่vec_1.end()+4ซึ่งอยู่นอกช่วง (out of bounds) ตัวอย่างข้างบนแก้ไขเป็นvec_1.begin()+4เพื่อคัดลอก 4 องค์ประกอบแรก (10,21,30,40) วางใน vec_2 ตำแหน่ง 1-4 (index 1-4) ทำให้ index 0 และ 5 เป็น 0