Creating Custom Stream Manipulators
#include <iostream>
#include <iomanip>
// Custom manipulator function
std::ostream& bold(std::ostream& os) {
return os << "\033[1m";
}
std::ostream& reset(std::ostream& os) {
return os << "\033[0m";
}
int main() {
std::cout << bold << "LabEx Formatting" << reset << std::endl;
return 0;
}
Implementing Stream Insertion Operators
graph TD
A[Custom Stream Formatting] --> B[Overload Insertion Operator]
A --> C[Create Custom Formatting Methods]
A --> D[Implement Stream Manipulators]
#include <iostream>
#include <sstream>
#include <iomanip>
class DataRecord {
private:
std::string name;
double value;
public:
DataRecord(const std::string& n, double v)
: name(n), value(v) {}
// Custom stream insertion operator
friend std::ostream& operator<<(std::ostream& os, const DataRecord& record) {
os << std::left << std::setw(15) << record.name
<< std::right << std::setw(10) << std::fixed
<< std::setprecision(2) << record.value;
return os;
}
};
int main() {
DataRecord record("Temperature", 98.6);
std::cout << record << std::endl;
return 0;
}
Technique |
Description |
Use Case |
Custom Manipulators |
Create specialized formatting functions |
Complex output formatting |
Stream Buffer Manipulation |
Direct buffer control |
Low-level stream operations |
Template-based Formatting |
Generic formatting solutions |
Flexible type handling |
#include <iostream>
#include <iomanip>
#include <type_traits>
template <typename T>
class FormattedOutput {
public:
static void print(const T& value, int width = 10) {
if constexpr (std::is_integral_v<T>) {
// Integer formatting
std::cout << std::setw(width) << std::hex
<< std::showbase << value;
} else if constexpr (std::is_floating_point_v<T>) {
// Floating-point formatting
std::cout << std::setw(width) << std::fixed
<< std::setprecision(2) << value;
} else {
// String-like formatting
std::cout << std::setw(width) << std::left << value;
}
}
};
int main() {
FormattedOutput<int>::print(255);
std::cout << std::endl;
FormattedOutput<double>::print(3.14159);
std::cout << std::endl;
FormattedOutput<std::string>::print("LabEx");
std::cout << std::endl;
return 0;
}
#include <iostream>
#include <functional>
class StreamFormatter {
public:
// Flexible formatting strategy
static void format(std::ostream& os,
const std::string& data,
std::function<void(std::ostream&, const std::string&)> formatter) {
formatter(os, data);
}
};
int main() {
// Lambda-based custom formatting
StreamFormatter::format(std::cout, "LabEx",
[](std::ostream& os, const std::string& str) {
os << "[" << str << "]";
});
return 0;
}
Key Takeaways
- Custom formatting provides ultimate flexibility
- Operator overloading enables complex output
- Template metaprogramming supports generic formatting
- Functional approaches allow dynamic formatting strategies
At LabEx, we believe in empowering developers with advanced formatting techniques that transcend basic output methods.