面试题答案
一键面试#include <iostream>
// 主模板,处理非指针类型
template<typename T>
typename std::enable_if<!std::is_pointer<T>::value, void>::type
metaFunc(const T& t) {
// 在此处对非指针类型进行操作,由于t是const引用,操作遵守常量性保证
std::cout << "处理非指针类型,常量性保证:对象不可修改" << std::endl;
}
// 模板特化,处理指针类型
template<typename T>
typename std::enable_if<std::is_pointer<T>::value, void>::type
metaFunc(const T& t) {
if (t != nullptr) {
// 在此处对指针类型进行操作,t是指向常量的指针的常量引用
// 可以访问对象,但不能通过t修改指针本身或指向的对象
std::cout << "处理指针类型,常量性保证:指针本身和指向的对象不可修改" << std::endl;
}
}
class MyType {
public:
int member;
MyType(int m) : member(m) {}
};
int main() {
const MyType obj(10);
metaFunc(obj);
const MyType* ptr = &obj;
metaFunc(ptr);
return 0;
}
实现思路解释
-
主模板:
- 使用
std::enable_if
和std::is_pointer
结合来判断T
是否为指针类型。std::enable_if<!std::is_pointer<T>::value, void>::type
确保只有当T
不是指针类型时,这个主模板才会被实例化。 - 函数参数为
const T& t
,保证了传入对象的常量性,在函数内部不能修改t
所引用的对象。
- 使用
-
模板特化:
std::enable_if<std::is_pointer<T>::value, void>::type
确保只有当T
是指针类型时,这个特化模板才会被实例化。- 函数参数同样为
const T& t
,这里t
是指向常量对象的指针的常量引用。这意味着不能通过t
修改指针本身(即不能让t
指向其他地方),也不能通过t
修改指向的对象。
-
不同情况下的常量性保证:
- 非指针类型:
const T& t
保证了传入对象在函数内部不可修改,从而遵守了常量性保证。 - 指针类型:
const T& t
保证了指针本身不可修改,并且由于指向的是常量对象,也不能通过指针修改指向的对象,满足了常量性语义。
- 非指针类型: