天津做网站制作,怎么做推广网站赌场,嘉兴网站建设设计制作,极速网站建设服务商目录 前言
提问
bard给出的答案
AI答案的问题
要求bard改进 人类智能
AI VS 人类 前言
通过本文读者可以学到modern C单例模式工厂模式的混合体#xff0c;同时也能看到#xff1a;如今AI发展到了怎样的智能程度#xff1f;怎样让AI帮助我们快速完成实现头脑中的想法单例模式工厂模式的混合体同时也能看到如今AI发展到了怎样的智能程度怎样让AI帮助我们快速完成实现头脑中的想法以及这样的智能程度会不会让程序员失业
提问
这次我不用ChatGPT了而是换成了bard. mzhai: Write a Modern c program to implement a singleton factory to produce 2 products. Each product has different arguments, the 1st has only one parameter of type int, the 2nd product has two parameters int and string respectively. 这里我特意提出要创建两个参数不同的产品防止AI写出来的类不通用有点像避免算法过拟合的感觉。
bard给出的答案 1 #include iostream2 #include memory3 #include utility45 enum class ProductType {6 Product1,7 Product28 };910 class Product {11 public:12 virtual ~Product() default;13 virtual void use() 0;14 };1516 // Concrete products with different arguments17 class Product1 : public Product {18 public:19 Product1(int arg1) : arg1_(arg1) {}20 void use() override { std::cout Using Product1 with arg1: arg1_ std::endl; }21 private:22 int arg1_;23 };2425 class Product2 : public Product {26 public:27 Product2(int arg2_1, std::string arg2_2) : arg2_1_(arg2_1), arg2_2_(arg2_2) {}28 void use() override { std::cout Using Product2 with arg2_1: arg2_1_ , arg2_2: arg2_2_ std::endl; }29 private:30 int arg2_1_;31 std::string arg2_2_;32 };3334 // Singleton factory with modern techniques35 class ProductFactory {36 public:37 static ProductFactory getInstance() {38 static ProductFactory instance;39 return instance;40 }4142 template typename... Args43 std::unique_ptrProduct createProduct(ProductType type, Args... args) {44 switch (type) {45 case ProductType::Product1:46 return std::make_uniqueProduct1(std::forwardArgs(args)...);47 case ProductType::Product2:48 return std::make_uniqueProduct2(std::forwardArgs(args)...);49 default:50 throw std::invalid_argument(Invalid product type);51 }52 }5354 private:55 ProductFactory() default; // Private constructor for singleton56 };5758 int main() {59 ProductFactory factory ProductFactory::getInstance();6061 std::unique_ptrProduct product1 factory.createProduct(ProductType::Product1, 42);62 std::unique_ptrProduct product2 factory.createProduct(ProductType::Product2, 5, Hello);6364 product1-use();65 product2-use();6667 return 0;68 }AI答案的问题
第一次给出的答案编译失败报错信息如下 /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c/12/bits/unique_ptr.h:1065:34: error: no matching constructor for initialization of Product2 1065 | { return unique_ptr_Tp(new _Tp(std::forward_Args(__args)...)); } | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/insights/insights.cpp:48:29: note: in instantiation of function template specialization std::make_uniqueProduct2, int requested here 48 | return std::make_uniqueProduct2(std::forwardArgs(args)...); | ^ 有点奇怪吧62行我们明明给Product2传的是两个参数不是有Product2才走case ProductType::Product2吗48行但编译器却抱怨给Product2的构造函数只传了一个int。这是为什么哪
这是因为case是运行时代码而createProduct根据61、62行会产生两个重载每个都包含全部代码。比如61行会产生如下code
std::unique_ptrProduct createProduct(ProductType type, int arg) {switch (type) {case ProductType::Product1:return std::make_uniqueProduct1(arg);case ProductType::Product2:return std::make_uniqueProduct2(arg);default:throw std::invalid_argument(Invalid product type);}
}
因为Product2的构造函数有两个参数而此处只有一个int arg), 故找不到匹配的构造函数。
要求bard改进
直接把错误贴给他它还是没能正真理解编译失败的原因之所以这么说是因为它给出的解决方案是
case ProductType::Product2:if constexpr (sizeof...(Args) 2) { // Ensure 2 arguments for Product2return std::make_uniqueProduct2(std::forwardArgs(args)...);} else {throw std::invalid_argument(Invalid arguments for Product2);} constexpr (sizeof...(Args) 2) 确实在编译阶段就判断除了TRUE/FALSE如果条件不符合这段代码就不走了从而导致61行实例出来的createProduct函数不报错但62行依然会报错看后面的cppinsights截图就会明白了。我们暂且按照这种思路试一试, 虽然它有问题后面会说。 1 #include iostream2 #include memory3 #include utility45 class Product {6 public:7 virtual ~Product() default;8 virtual void use() 0;9 };1011 // Concrete products with different arguments12 class Product1 : public Product {13 public:14 Product1(int arg1) : arg1_(arg1) {}15 void use() override { std::cout Using Product1 with arg1: arg1_ std::endl; }16 private:17 int arg1_;18 };1920 class Product2 : public Product {21 public:22 Product2(int arg2_1, std::string arg2_2) : arg2_1_(arg2_1), arg2_2_(arg2_2) {}23 void use() override { std::cout Using Product2 with arg2_1: arg2_1_ , arg2_2: arg2_2_ std::endl; }24 private:25 int arg2_1_;26 std::string arg2_2_;27 };2829 class ProductFactory {30 public:31 static ProductFactory getInstance() {32 static ProductFactory instance;33 return instance;34 }35 template typename... Args36 std::unique_ptrProduct createProduct(Args... args) {37 if constexpr (sizeof...(Args) 1){38 return std::make_uniqueProduct1(std::forwardArgs(args)...);39 }40 if constexpr (sizeof...(Args) 2){41 return std::make_uniqueProduct2(std::forwardArgs(args)...);42 }43 }44 private:45 ProductFactory() default; // Private constructor for singleton46 };4748 int main() {49 ProductFactory factory ProductFactory::getInstance();5051 std::unique_ptrProduct product1 factory.createProduct(42);52 std::string hi(Hello);53 std::unique_ptrProduct product2 factory.createProduct(5, hi);5455 product1-use();56 product2-use();5758 return 0;59 }编译成功运行也没问题。我们还可以通过cppinsights.io看看模板函数实例化出来的2个重载结果 显然这种办法不好
请想一想如果product1 和Product2都只有一个参数哪就无法通过sizeof区分了。而且这么做产生了很多无用代码if constexpr...
人类智能
所以还是由我给它快速改一改吧。我们直接给createProduct函数多传一个模板参数进去比如叫T像下面这样
template typename T, typename... Args
std::unique_ptrT createProduct(Args... args) {return std::make_uniqueT(std::forwardArgs(args)...);
}...std::unique_ptrProduct product1 factory.createProductProduct1(42);
std::string hi(Hello);
std::unique_ptrProduct product2 factory.createProductProduct2(5, hi);看下createProduct如何实例化的 问一下bard这么改怎么样回答的井井有条 mzhaiHow about changing the code to above Bard Im happy to review the proposed code changes: Key Changes: Templated createProduct function: The createProduct function now takes a template parameter T to specify the product type, eliminating the need for the ProductType enum. 传了T就没必要传ProductType enum了Removal of switch statement: The switch statement is no longer needed as the compiler determines the correct type based on the template argument.createProduct中的Switch可以去掉了Explicit product type in main: The createProduct function is called with explicit template arguments (Product1 and Product2) to create the desired product types.main中要显示指定产品类型即尖括号中的Product1、Product2 Analysis: Pros: More concise and less verbose code. 代码简明Leverages template metaprogramming for type-driven behavior.利用了模板元编程Potentially easier to extend for new product types.新产品类型扩展更容易Cons: Might be less readable for those less familiar with templates.对不熟悉模板的人来说可读性变差Error messages might be more cryptic due to template instantiation.因为模板实例导致报错信息比较神秘不那么直接确实Doesnt enforce a closed set of product types (could potentially create other types).没有强制指定哪些产品类型能生产有产生别的类型的风险 Overall: The changes are valid and adhere to modern C practices.The choice between this approach and the previous one using the ProductType enum is mainly a matter of preference and trade-offs.Consider the teams familiarity with templates and the specific project requirements when deciding on the best approach. Additional Notes: Ensure that all product classes (Product1, Product2, etc.) are derived from the Product base class for this approach to work correctly.Consider using static_assert or concepts (if available in your C version) to enforce constraints on the template parameter T, ensuring its a valid product type. AI VS 人类
AI确实智商还有限但也确实能提高编程效率copilot等等一般宣传能提高人类编程效率50%左右在没有增量就业机会的情况下也就是一半工程师要失业了
附上最终代码
便于大家COPY及实验。
#include iostream
#include memory
#include utilityclass Product {
public:virtual ~Product() default;virtual void use() 0;
};// Concrete products with different arguments
class Product1 : public Product {
public:Product1(int arg1) : arg1_(arg1) {}void use() override { std::cout Using Product1 with arg1: arg1_ std::endl; }
private:int arg1_;
};class Product2 : public Product {
public:Product2(int arg2_1, std::string arg2_2) : arg2_1_(arg2_1), arg2_2_(arg2_2) {}void use() override { std::cout Using Product2 with arg2_1: arg2_1_ , arg2_2: arg2_2_ std::endl; }
private:int arg2_1_;std::string arg2_2_;
};class ProductFactory {
public:static ProductFactory getInstance() {static ProductFactory instance;return instance;}template typename T, typename... Args//typename std::enable_ifstd::is_sameProduct,T::value, void::typestd::unique_ptrT createProduct(Args... args) {return std::make_uniqueT(std::forwardArgs(args)...);}private:ProductFactory() default; // Private constructor for singleton
};int main() {ProductFactory factory;std::unique_ptrProduct product1 factory.createProductProduct1(42);std::string hi(Hello);std::unique_ptrProduct product2 factory.createProductProduct2(5, hi);product1-use();product2-use();return 0;
}