MST

星途 面试题库

面试题:C++成员函数在复杂模板元编程中区分对象数据的实现

假设你正在进行C++模板元编程,有一个模板类 `TemplateClass` 如下: ```cpp template <typename T> class TemplateClass { T data; public: TemplateClass(T val) : data(val) {} void processData(); }; ``` 在 `processData` 函数中,要求根据 `T` 的类型(如 `int`、`double`、自定义类等)以不同方式处理对象的 `data` 成员,同时要确保在编译期完成类型判断和数据处理逻辑,以实现高效的编译期优化。请详细描述如何实现这一功能,并给出完整的代码实现。
38.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 使用 std::enable_if 和 SFINAE(Substitution Failure Is Not An Error)实现编译期类型判断

    • std::enable_if 是一个类型特性,它可以根据条件来选择是否定义某个类型。SFINAE 是一种机制,当模板实例化过程中出现替换失败时,不会产生错误,而是该模板被忽略。
    • 对于不同的 T 类型,我们可以定义不同的 processData 重载版本,通过 std::enable_if 来控制每个版本何时可用。
  2. 代码实现

#include <iostream>
#include <type_traits>

template <typename T>
class TemplateClass {
    T data;
public:
    TemplateClass(T val) : data(val) {}

    // 处理 int 类型的特化版本
    template <typename = std::enable_if_t<std::is_same_v<T, int>>>
    void processData() {
        std::cout << "Processing int data: " << data << std::endl;
    }

    // 处理 double 类型的特化版本
    template <typename = std::enable_if_t<std::is_same_v<T, double>>>
    void processData() {
        std::cout << "Processing double data: " << data << std::endl;
    }

    // 处理自定义类类型的通用版本
    template <typename = std::enable_if_t<!std::is_arithmetic_v<T>>>
    void processData() {
        std::cout << "Processing custom class data." << std::endl;
    }
};

// 自定义类示例
class CustomClass {
public:
    CustomClass() = default;
};

int main() {
    TemplateClass<int> intObj(10);
    intObj.processData();

    TemplateClass<double> doubleObj(3.14);
    doubleObj.processData();

    TemplateClass<CustomClass> customObj;
    customObj.processData();

    return 0;
}

在上述代码中:

  • 针对 int 类型,定义了一个 processData 的重载版本,通过 std::enable_if_t<std::is_same_v<T, int>> 确保只有当 Tint 类型时该版本才可用。
  • 针对 double 类型同理。
  • 对于自定义类类型,使用 std::enable_if_t<!std::is_arithmetic_v<T>> 来确保处理非算术类型(即自定义类),因为自定义类不属于算术类型。
  • main 函数中,创建了不同类型的 TemplateClass 对象并调用 processData 函数,展示了针对不同类型的不同处理逻辑。