目录
1. 限制模板函数的模板参数类型
2. CRTP (Curiously Recurring Template Pattern)
3. 元编程+insights
4. 完美转发
5. 工厂模式
6. Lamdba表达式
7. RAII - 自动释放资源
8. 其它小伎俩
1. 限制模板函数的模板参数类型
#include <iostream>
#include <type_traits>
// Expected class type
class MyClass {};
// Function template using std::enable_if to check if the type is MyClass
template<typename T>
typename std::enable_if<std::is_same<T, MyClass>::value, void>::type
checkType() {
std::cout << "Type is MyClass" << std::endl;
}
int main() {
checkType<int>(); // Won't compile, int is not MyClass
checkType<MyClass>(); // Will compile and print "Type is MyClass"
return 0;
}
2. CRTP (Curiously Recurring Template Pattern)
template <typename Derived>
struct Base {
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
struct Derived : Base<Derived> {
void implementation() {
// Implementation details
}
};
// Usage
Derived d;
d.interface(); // Calls Derived::implementation()
CRTP + std::enable_shared_from_this<>
class Test: public std::enable_shared_from_this<Test>
{
std::shared_ptr<Test> GetPtr(){
return shared_from_this();
}
static std::shared_ptr<Test> Create(){
return std::shared_ptr<Test>(new Test());
}
private://imply constructor, so you couldn't create a object pointed by Test*
Test() = default;
};
3. 元编程+insights
template <int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
template <>
struct Factorial<0> {
static const int value = 1;
};
// Usage
int result = Factorial<5>::value; // result = 120
元编程不易理解,有个在线平台可以看到模板展开的样子
4. 完美转发
#include <iostream>
#include <utility>
void process(int& value) {
std::cout << "L-value reference: " << value << std::endl;
}
void process(int&& value) {
std::cout << "R-value reference: " << value << std::endl;
}
template<typename T>
void forward(T&& value) {
process(std::forward<T>(value));
}
// Usage
int a = 5;
forward(a); // Output: L-value reference: 5
forward(10); // Output: R-value reference: 10
5. 工厂模式
#include <iostream>
class Product {
public:
virtual void printInfo() = 0;
};
class ConcreteProduct : public Product {
public:
void printInfo() override {
std::cout << "Concrete Product" << std::endl;
}
};
class Factory {
public:
virtual Product* createProduct() = 0;
};
class ConcreteFactory : public Factory {
public:
Product* createProduct() override {
return new ConcreteProduct();
}
};
6. Lamdba表达式
#include <iostream>
void exampleLambda() {
int increment = 5;
auto addIncrement = [increment](int x) { return x + increment; };
std::cout << addIncrement(10) << std::endl; // Output: 15
}
7. RAII - 自动释放资源
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
class FileResource {
public:
explicit FileResource(const std::string& filename)
: fileStream(filename) {
if (!fileStream.is_open()) {
throw std::runtime_error("Unable to open file");
}
std::cout << "File opened: " << filename << std::endl;
}
~FileResource() {
if (fileStream.is_open()) {
fileStream.close();
std::cout << "File closed" << std::endl;
}
}
void writeToFile(const std::string& data) {
fileStream << data << std::endl;
}
private:
std::ofstream fileStream;
};
int main() {
try {
FileResource file("example.txt");
file.writeToFile("Hello, RAII!");
// File automatically closed when 'file' goes out of scope
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
此思想经常用来加解锁。
8. 其它小伎俩
int mi = std::min({x1, x2, x3, x4});
#include <bits/stdc++.h> //all headers in one
auto
emplace_back is better than push_back
std::tuple<int, char, std::string> tp = std::make_tuple(1,'a',"bc");
std::cout<<std::get<0>(tp);
auto [i,c,s] = tp; //c++17
//deep copy
std::copy_n(arr1,n,arr2);
std::all_of
std::any_of
std::none_of
未完待续。。。