MST

星途 面试题库

面试题:C++ 按常量引用传递在模板元编程中的常量性保证

在C++ 模板元编程环境下,考虑如下代码: ```cpp #include <iostream> template<typename T> void metaFunc(const T& t) { // 假设T是一个自定义类型,在此处如何通过模板元编程技术确保 // 对t的操作严格遵守按常量引用传递的常量性保证,同时 // 利用模板特化实现对不同类型(如指针类型和非指针类型) // 的不同处理,且要保证常量性语义在各种情况下的正确性。 } class MyType { public: int member; MyType(int m) : member(m) {} }; int main() { const MyType obj(10); metaFunc(obj); return 0; } ``` 请实现 `metaFunc` 函数模板,满足上述要求,并详细解释你的实现思路以及在不同情况下如何保证常量性。
13.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#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;
}

实现思路解释

  1. 主模板

    • 使用 std::enable_ifstd::is_pointer 结合来判断 T 是否为指针类型。std::enable_if<!std::is_pointer<T>::value, void>::type 确保只有当 T 不是指针类型时,这个主模板才会被实例化。
    • 函数参数为 const T& t,保证了传入对象的常量性,在函数内部不能修改 t 所引用的对象。
  2. 模板特化

    • std::enable_if<std::is_pointer<T>::value, void>::type 确保只有当 T 是指针类型时,这个特化模板才会被实例化。
    • 函数参数同样为 const T& t,这里 t 是指向常量对象的指针的常量引用。这意味着不能通过 t 修改指针本身(即不能让 t 指向其他地方),也不能通过 t 修改指向的对象。
  3. 不同情况下的常量性保证

    • 非指针类型const T& t 保证了传入对象在函数内部不可修改,从而遵守了常量性保证。
    • 指针类型const T& t 保证了指针本身不可修改,并且由于指向的是常量对象,也不能通过指针修改指向的对象,满足了常量性语义。