面试题答案
一键面试设计思路
- 类型安全:利用模板元编程在编译期检查类型,确保参与运算的类型符合预期。通过模板参数推导和SFINAE(Substitution Failure Is Not An Error)机制,排除不支持的类型组合。
- 高效运算:借助模板特化,针对特定类型组合提供优化的实现。编译期计算可以避免运行时的额外开销,如条件判断和函数调用开销。同时,编译器可以对模板实例化的代码进行优化。
- 普通函数实现运算符重载:使用普通函数而不是成员函数进行运算符重载,这样可以更好地支持非成员类型(如自定义结构体)的运算,并且在模板元编程场景中更灵活。普通函数可以通过友元函数访问类的私有成员,同时也方便利用命名空间进行函数重载管理。
关键代码示例
#include <iostream>
// 模板元编程工具,用于判断类型是否为数值类型
template<typename T>
struct IsNumeric {
static constexpr bool value = false;
};
template<>
struct IsNumeric<int> {
static constexpr bool value = true;
};
template<>
struct IsNumeric<double> {
static constexpr bool value = true;
};
// 普通函数实现加法运算符重载
template<typename T, typename U,
typename = std::enable_if_t<IsNumeric<T>::value && IsNumeric<U>::value>>
auto operator+(T a, U b) {
return a + b;
}
// 示例自定义类型
struct Complex {
double real;
double imag;
// 友元函数声明,以便访问私有成员(如果有)
friend Complex operator+(const Complex& a, const Complex& b);
};
// 针对Complex类型的加法运算符重载
Complex operator+(const Complex& a, const Complex& b) {
return {a.real + b.real, a.imag + b.imag};
}
int main() {
int a = 5;
double b = 3.5;
auto result1 = a + b;
std::cout << "result1: " << result1 << std::endl;
Complex c1 = {1.0, 2.0};
Complex c2 = {3.0, 4.0};
Complex result2 = c1 + c2;
std::cout << "result2: (" << result2.real << ", " << result2.imag << ")" << std::endl;
return 0;
}
上述代码中:
IsNumeric
模板结构体用于判断类型是否为数值类型,通过特化实现对int
和double
的支持。operator+
模板函数利用std::enable_if_t
和IsNumeric
实现类型安全,只允许数值类型参与运算。- 针对自定义类型
Complex
,通过普通函数重载operator+
实现复数加法。这样既保证了类型安全,又利用模板元编程和普通函数运算符重载实现了高效的运算。