Template Variadik
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 67 dari 104.
Bagaimana jika kamu memerlukan fungsi yang menerima argumen dalam jumlah berapa pun dengan tipe apa pun? Template tradisional mengharuskan kamu menentukan secara persis jumlah parameter tipe yang diperlukan. Template variadik mengatasi hal ini dengan memungkinkan template menerima argumen template dalam jumlah yang tidak terbatas.
Sintaks menggunakan ... (elipsis) untuk membuat paket parameter:
template <typename... Args>
void printAll(Args... args) {
// Args adalah paket parameter template
// args adalah paket parameter fungsi
}Untuk memproses argumen, biasanya kamu menggunakan rekursi dengan kasus dasar. Paket parameter mengembang satu argumen setiap kali hingga tidak ada yang tersisa:
// Kasus dasar: tidak ada argumen tersisa
void print() {
std::cout << std::endl;
}
// Kasus rekursif: proses argumen pertama, lalu lakukan rekursi dengan sisanya
template <typename T, typename... Rest>
void print(T first, Rest... rest) {
std::cout << first << " ";
print(rest...); // Uraikan argumen yang tersisa
}
print(1, 3.14, "hello", 'x'); // output: 1 3.14 hello xKamu juga bisa menggunakan ekspresi fold (C++17) untuk operasi yang lebih sederhana tanpa rekursi eksplisit:
template <typename... Args>
auto sum(Args... args) {
return (args + ...); // Ekspresi fold: menjumlahkan semua argumen
}
std::cout << sum(1, 2, 3, 4) << std::endl; // output: 10Template variadik mendukung banyak fitur standard library seperti std::make_unique, std::tuple, dan std::function. Template ini memungkinkan fungsi yang aman dari segi tipe dan dapat bekerja dengan kombinasi jenis serta jumlah argumen apa pun.
Tantangan
MudahMari bangun sistem pencatatan log yang fleksibel dengan template variadik untuk menangani pesan dengan jumlah argumen berapa pun. Kamu akan membuat utilitas yang dapat menggabungkan nilai, menghitung argumen, dan mencetak output berformat, semuanya menggunakan pack parameter.
Kamu akan mengatur kodemu dalam dua file:
Variadic.h: Definisikan fungsi template variadik di sini.Buat fungsi
printAllyang mencetak semua argumennya dengan spasi sebagai pemisah, lalu diikuti baris baru. Gunakan pendekatan rekursif dengan kasus dasar yang hanya mencetak baris baru, dan kasus rekursif yang mencetak argumen pertama, sebuah spasi, lalu memanggil kembali fungsi dengan argumen yang tersisa.Buat fungsi
countArgsyang mengembalikan jumlah argumen yang diteruskan kepadanya. Gunakansizeof...untuk mendapatkan ukuran pack parameter.Buat fungsi
sumyang menjumlahkan semua argumen numerik dan mengembalikan hasilnya. Gunakan ekspresi fold dengan operator+.Buat fungsi
productyang mengalikan semua argumen numerik dan mengembalikan hasilnya. Gunakan ekspresi fold dengan operator*.main.cpp: Baca empat input, masing-masing pada baris terpisah:- Bilangan bulat
- Bilangan double
- String
- Karakter
Demonstrasikan template variadikmu dengan:
- Memanggil
printAlldengan keempat input dan mencetak hasilnya - Mencetak jumlah argumen saat memanggil
countArgsdengan bilangan bulat, double, dan karakter:Argument count: <count> - Menghitung jumlah bilangan bulat, double, serta nilai 10 dan 5, lalu mencetak:
Sum: <result> - Menghitung hasil perkalian bilangan bulat dengan nilai 2 dan 3, lalu mencetak:
Product: <result> - Memanggil
printAllhanya dengan string sebagai argumen tunggal - Memanggil
printAlltanpa argumen, yang seharusnya hanya mencetak baris baru
Contohnya, dengan input 5, 2.5, Hello, dan X:
5 2.5 Hello X
Argument count: 3
Sum: 22.5
Product: 30
Hello
Perhatikan bagaimana printAll menangani jumlah argumen dengan tipe campuran berapa pun, dari empat argumen hingga nol. Fungsi sum dan product menggunakan ekspresi fold untuk menggabungkan semua nilai dengan cara yang ringkas tanpa rekursi eksplisit. Fungsi countArgs-mu menunjukkan bagaimana sizeof... memberimu ukuran pack saat kompilasi.
Coba sendiri
#include <iostream>
#include <string>
#include "Variadic.h"
using namespace std;
int main() {
// Baca input
int intVal;
double doubleVal;
string strVal;
char charVal;
cin >> intVal;
cin >> doubleVal;
cin >> strVal;
cin >> charVal;
// TODO: Panggil printAll dengan keempat input
// TODO: Cetak jumlah argumen menggunakan countArgs dengan intVal, doubleVal, dan charVal
// Format: "Argument count: <count>"
// TODO: Hitung dan cetak jumlah dari intVal, doubleVal, 10, dan 5
// Format: "Sum: <result>"
// TODO: Hitung dan cetak hasil kali intVal, 2, dan 3
// Format: "Product: <result>"
// TODO: Panggil printAll hanya dengan string
// TODO: Panggil printAll tanpa argumen
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online