MST

星途 面试题库

面试题:C++中class与struct在模板元编程中的潜在差异及应用场景

在C++的模板元编程场景下,class与struct可能存在哪些潜在的差异?结合模板偏特化、全特化以及模板元函数等概念,举例说明这些差异在实际复杂模板编程中的应用场景及选择依据。
47.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 默认访问控制
    • 差异:在class中,成员默认是private访问权限;而在struct中,成员默认是public访问权限。
    • 模板元编程应用场景:在模板元函数中,若希望某些辅助类型或函数仅在内部使用,可使用class将其成员设为private,增强封装性。例如:
template <typename T>
class MetaFunction {
private:
    using InnerType = typename std::conditional<std::is_integral<T>::value, int, void>::type;
public:
    static const bool value = std::is_same<InnerType, int>::value;
};

这里InnerType是内部辅助类型,设为private避免外部直接访问。若使用struct,则需手动将InnerType设为private。 2. 模板偏特化和全特化

  • 差异:从语法角度,classstruct在模板特化声明上基本相同,但由于默认访问控制差异会导致使用场景不同。
  • 应用场景:在模板偏特化场景下,假设我们有一个模板类用于处理不同类型的序列化。
template <typename T>
struct Serializer {
    static std::string serialize(const T& obj) {
        // 通用序列化逻辑
        return "generic serialization";
    }
};

template <typename T>
class Serializer<T*> {
public:
    static std::string serialize(const T* obj) {
        // 指针类型序列化逻辑
        return "pointer serialization";
    }
};

这里Serializer<T*>使用class进行偏特化,由于class默认private,可将一些内部实现细节隐藏,只暴露serialize接口。若使用struct,则需手动控制访问权限。

  • 选择依据:若希望在特化模板类中有更多内部实现细节隐藏,倾向于使用class;若希望特化模板类成员更开放,易于外部访问和扩展,可使用struct
  1. 继承和模板元函数结合
    • 差异:在继承关系中,class默认是private继承,而struct默认是public继承。这在模板元编程构建类型层次结构时会有不同效果。
    • 应用场景:例如,在构建一个类型特征模板层次结构时。
template <typename T>
struct BaseTypeTraits {
    static const bool is_fundamental = false;
};

template <typename T>
class DerivedTypeTraits : private BaseTypeTraits<T> {
public:
    static const bool is_integral = std::is_integral<T>::value;
};

这里DerivedTypeTraits使用class私有继承BaseTypeTraits,隐藏BaseTypeTraits的部分接口,仅暴露自己的is_integral接口。若使用struct,默认的public继承会使BaseTypeTraitsis_fundamental也对外可见,这可能不符合某些需求。

  • 选择依据:如果希望在模板元编程构建的类型层次结构中,对基类接口有选择地暴露,根据是否需要隐藏基类接口来选择class(隐藏)或struct(暴露)继承方式。