电商型企业网站建设,建立网站的作用,凡科门店通,电商网站技术方案目录
一、书中第一题
二、书中第三题
三、书中第五题
四、书中第六题
五、书中第七题
六、书中十一题
七、书中十二题
八、 书中十三题
总结 一、书中第一题
#include iostreamtemplate typename T, size_t N
struct NSVarTypeDict {static void Cre…目录
一、书中第一题
二、书中第三题
三、书中第五题
四、书中第六题
五、书中第七题
六、书中十一题
七、书中十二题
八、 书中十三题
总结 一、书中第一题
#include iostreamtemplate typename T, size_t N
struct NSVarTypeDict {static void Create_() {CreateHelperN, T();}private:template size_t M, typename Ustruct CreateHelper {static void Apply() {// 构造元素的逻辑std::cout Constructing element at index M std::endl;CreateHelperM - 1, U::Apply();CreateHelperM - 1, U::Apply();}};template typename Ustruct CreateHelper0, U {static void Apply() {// 基础情况当索引为0时停止递归}};
};int main() {NSVarTypeDictint, 8::Create_();return 0;
}
二、书中第三题
#include iostream
#include type_traitstemplate size_t N, size_t M, typename T1, typename T2
struct NSVarTypeDict {using NewTupleType_ std::conditional_tN M, T1, T2;
};int main() {struct Type1 {int value;};struct Type2 {double value;};typename NSVarTypeDict3, 4, Type1, Type2::NewTupleType_ var1; // 选择Type2typename NSVarTypeDict5, 5, Type1, Type2::NewTupleType_ var2; // 选择Type1return 0;
}
代码结构更清晰通过使用std::conditional_t将特化1和特化2合并成一个表达式避免了重复的代码逻辑和声明。可维护性提高合并后的代码更加简洁易于阅读和理解。
在使用std::conditional_t进行合并后简化的代码更易于理解和维护并且避免了重复代码的问题因此整体上更具优势。
三、书中第五题
#include iostreamclass VarTypeDict {
public:templatetypename Tvoid Set(T value) {// 只能用于右值的Set函数实现std::cout Setting value for rvalue: value std::endl;}templatetypename Tvoid Set(T value) {// 能用于左值的Set函数实现std::cout Setting value for lvalue: value std::endl;}
};int main() {VarTypeDict::Values values;int x 10;values.Set(x); // 调用能用于左值的Set函数values.Set(20); // 调用只能用于右值的Set函数return 0;
}
优势和劣势
优势
能用于左值的函数可以接受左值类型的参数提供更灵活的使用方式。通过重载的方式程序可以根据传入值的类型来选择合适的函数重载提高了程序的通用性和适用性。
劣势
在某些情况下程序员需要知道传入的值是左值还是右值否则会导致调用不符合预期的函数。
总体上能用于左值的函数相比只能用于右值的函数更加灵活可以接受更多种类的参数但需要谨慎使用以避免潜在的问题。
四、书中第六题
将构造函数的访问权限从public修改为private或protected是一种有效的封装手段可以限制其它类对构造函数的直接访问从而更好地控制类的实例化。
理由
控制类的实例化通过将构造函数的访问权限设为private或protected可以防止该类被直接实例化从而强制使用特定的接口或方法来获取该类的实例。封装实现细节将构造函数的访问权限限制在类内部有助于隐藏实现细节提高类的封装性和安全性。限制子类的实例化将构造函数的访问权限设为protected可以使子类能够调用构造函数但限制外部代码直接实例化子类。
接下来让我们尝试将Values的构造函数访问权限从public修改为private然后编译检查是否符合预期。
class VarTypeDict {
public:class Values {private: // 修改构造函数的访问权限为privateValues() {}friend class VarTypeDict; // 允许VarTypeDict类访问构造函数public:templatetypename Tvoid Set(T value) {std::cout Setting value for rvalue: value std::endl;}templatetypename Tvoid Set(T value) {std::cout Setting value for lvalue: value std::endl;}};
};
根据上述代码修改我们将Values的构造函数的访问权限修改为private并使用friend关键字允许VarTypeDict类访问构造函数。
在实际编译时会发现尝试在外部进行Values类的实例化会导致编译错误而在VarTypeDict类中可以正常调用构造函数来创建Values的实例符合我们的预期。
这种修改符合我们的预期成功限制了外部代码对Values类的直接实例化增强了类的封装性和安全性。
五、书中第七题
#include iostream
#include tupleclass VarTypeDict {
public:class Values {private:std::tupleint, double, std::string data; // 使用std::tuple替换指针数组public:templatetypename Tvoid Set(T value) {std::getT(data) value; // 使用std::get获取元素}templatetypename TT Get() {return std::getT(data); // 使用std::get获取元素}};
};
示例中使用std::tuple替换了指针数组这样就不需要显式进行内存分配和释放。通过std::get函数我们可以在不了解具体元素类型的情况下访问和操作特定类型的元素。
新版本的复杂度分析
时间复杂度使用std::tuple并不会增加操作的时间复杂度因为std::tuple内部通常是通过继承和模板特化来实现的因此元素访问的操作也是常数时间复杂度。空间复杂度使用std::tuple可能会略微增加一些内存消耗因为std::tuple通常会引入一些辅助结构来实现元素访问的功能。
总体而言通过使用std::tuple替换指针数组新版本的VarTypeDict复杂度并未明显增加并且更加安全和易用因为不再需要显式操作内存分配与释放同时使用std::tuple提供了更好的类型安全性和代码可读性。
六、书中十一题
#include iostream// 定义策略类模板
template typename T
class Policy {
public:void DoSomething() {std::cout Doing something with type typeid(T).name() std::endl;}
};// 定义宏来简化策略对象的定义
#define POLICY_POLICY(PolicyType, ValueType) PolicyPolicyTypeValueTypeint main() {// 构造模板策略对象POLICY_POLICY(std::vector, int) policyObject;// 使用策略对象policyObject.DoSomething();return 0;
}
七、书中十二题
#include iostream
#include type_traits
#include utilityclass NamedParameters {
public:class Values {private:int value;public:Values(int val) : value(val) {}templatetypename TT Get() const {return T(value); // 复制构造返回值}templatetypename Ttypename std::remove_constT::type Get() {return std::move(value); // 返回右值引用使用移动语义}};
};int main() {NamedParameters::Values values(123);// 使用左值引用调用Get函数int copyValue values.Getint();std::cout Copy Value: copyValue std::endl;// 使用右值引用调用Get函数int moveValue std::move(values).Getint();std::cout Move Value: moveValue std::endl;return 0;
}
示例中我们在NamedParameters::Values类中引入了一个新的Get函数模板并使用std::remove_const来移除返回类型的const限定符。在Get函数的右值引用版本中我们使用std::move对底层数据对象进行移动通过移动语义返回右值引用。这样对于右值引用的情况我们可以通过移动来返回底层数据对象减少了额外的复制成本。
在主函数中我们首先使用左值引用调用Get函数对底层数据对象进行复制。然后我们使用std::move将values对象转换为右值引用并调用Get函数获取右值引用的底层数据对象。通过输出的结果我们可以看到使用移动语义获取的值。
通过引入移动语义的Get函数我们可以根据NamedParameters::Values对象的左值或右值特性使用不同的方式返回底层数据对象从而减少复制带来的额外消耗。
八、 书中十三题
#include iostream
#include type_traits// 定义异类词典模板
templatetypename... Ts
struct VarTypeDict {};// 添加元素的元函数 AddItem
template typename Dict, typename NewItem
struct AddItem;// 特化向空的异类词典添加元素
template typename NewItem
struct AddItemVarTypeDict, NewItem {using type VarTypeDictNewItem;
};// 特化向非空的异类词典添加元素
template typename Head, typename... Tail, typename NewItem
struct AddItemVarTypeDictHead, Tail..., NewItem {using type typename std::conditionalstd::is_sameHead, NewItem::value, VarTypeDictHead, Tail..., typename AddItemVarTypeDictTail..., NewItem::type::type;
};// 删除元素的元函数 DelItem
template typename Dict, typename ItemToDelete
struct DelItem;// 特化从空的异类词典删除元素报错
template typename ItemToDelete
struct DelItemVarTypeDict, ItemToDelete {static_assert(sizeof(ItemToDelete) 0, Item does not exist in VarTypeDict);
};// 特化从包含元素的异类词典删除元素
template typename Head, typename... Tail, typename ItemToDelete
struct DelItemVarTypeDictHead, Tail..., ItemToDelete {using type typename std::conditionalstd::is_sameHead, ItemToDelete::value, VarTypeDictTail..., typename AddItemtypename DelItemVarTypeDictTail..., ItemToDelete::type, Head::type::type;
};int main() {// 使用示例添加元素using MyDict VarTypeDictstruct A, struct B;using DictWithMoreItems typename AddItemMyDict, struct C::type;using DictWithLessItems typename DelItemMyDict, A::type;// 使用示例删除不存在的元素会报错// using DictWithInvalidDel typename DelItemMyDict, C::type; // 会产生编译时错误std::cout typeid(DictWithMoreItems).name() std::endl; // 输出 VarTypeDictA, B, Cstd::cout typeid(DictWithLessItems).name() std::endl; // 输出 VarTypeDictBreturn 0;
}
示例中我们定义了AddItem和DelItem两个元函数来实现添加和删除元素。通过模板特化和递归调用我们可以实现对异类词典的元素操作。在DelItem的特化中我们使用静态断言来检测是否要删除的元素存在于异类词典中以便在编译时发现错误。
在主函数中我们使用示例展示了AddItem与DelItem元函数的使用方式并输出了修改后的异类词典类型。同时我们还展示了尝试删除不存在的元素时会触发编译时错误的情况。
通过这种方式我们可以在编译期间操作异类词典的元素动态地修改异类词典的类型。 总结
下一章开始学习深度学习简介