AI駆動のコード生成は、高度なモデルを活用してコードを書き、最適化し、理解するもので、ソフトウェア開発のますます重要な側面となっています。しかし、AIは開発者を置き換えるためのものではなく、彼らの仕事を支援するためのものです。最終的に、AIの提案をどう使うかを決めるのは人間です。GPT-4oに投げかけた次のクエリを考えてみましょう:
2つの大きな整数を加算するC++関数をください
回答は次のとおりです:
C++で2つの大きな整数を加算するには、 string データ型を使用して任意の大きさの数値を扱えます。文字列として表現された2つの大きな整数を加算する関数は次のとおりです:
#include <iostream>
#include <string>
#include <algorithm>
// Function to add two big integers
std::string addBigIntegers(const std::string& num1, const std::string& num2) {
std::string result = "";
int carry = 0;
// Make sure num1 is the longer string
std::string n1 = num1.size() >= num2.size() ? num1 : num2;
std::string n2 = num1.size() < num2.size() ? num1 : num2;
// Reverse the strings to make addition easier
std::reverse(n1.begin(), n1.end());
std::reverse(n2.begin(), n2.end());
// Add digit by digit
for (size_t i = 0; i < n1.size(); ++i) {
int digit1 = n1[i] - '0';
int digit2 = i < n2.size() ? n2[i] - '0' : 0;
int sum = digit1 + digit2 + carry;
carry = sum / 10;
result.push_back((sum % 10) + '0');
}
// If there is a carry left, add it
if (carry) {
result.push_back(carry + '0');
}
// Reverse the result to get the final sum
std::reverse(result.begin(), result.end());
return result;
}
int main() {
std::string num1, num2;
// Prompt the user for the first big integer
std::cout << "Enter the first big integer: ";
std::cin >> num1;
// Prompt the user for the second big integer
std::cout << "Enter the second big integer: ";
std::cin >> num2;
// Call the addBigIntegers function and store the result
std::string sum = addBigIntegers(num1, num2);
// Output the result
std::cout << "The sum of " << num1 << " and " << num2 << " is " << sum << "." << std::endl;
return 0;
}
この回答の問題は、クエリの解釈方法にあります。この例では、GPTはそのようなケースのためにオンラインで入手できる多くのソリューションと同様に、非常に大きな数値を扱うのに適したソリューションを提供しています。しかし、開発者の「大きな数値」の定義が最大10億までの値しか含まない場合はどうでしょうか?
このシナリオでは、明確に定義されたコンテキストがないために、コードを不必要に複雑にする可能性のある、過剰に設計されたソリューションに遭遇します。AIでコードを生成する際、コンテキストは重要な役割を果たし、一般的な指示を提供するのではなく、要件を正確に指定することの重要性を浮き彫りにしています。
コンテキストの重要性を強調するために、別の例を見てみましょう。
ファイルにオブジェクトを保存して取得するC++コードをください
回答は次のとおりです:
#include <iostream>
#include <fstream>
#include <string>
class Person {
public:
std::string name;
int age;
// Constructor
Person() : name(""), age(0) {}
Person(const std::string& n, int a) : name(n), age(a) {}
// Method to display the person's information
void display() const {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}
// Friend functions for serialization and deserialization
friend std::ofstream& operator<<(std::ofstream& ofs, const Person& p);
friend std::ifstream& operator>>(std::ifstream& ifs, Person& p);
};
// Overload the << operator for writing a Person object to a file
std::ofstream& operator<<(std::ofstream& ofs, const Person& p) {
ofs << p.name << std::endl;
ofs << p.age << std::endl;
return ofs;
}
// Overload the >> operator for reading a Person object from a file
std::ifstream& operator>>(std::ifstream& ifs, Person& p) {
std::getline(ifs, p.name);
ifs >> p.age;
ifs.ignore(); // Ignore the newline character after reading age
return ifs;
}
そしてmain関数:
int main() {
// Create a Person object
Person p1("John Doe", 30);
// Save the object to a file
std::ofstream ofs("person.txt");
if (ofs.is_open()) {
ofs << p1;
ofs.close();
std::cout << "Person saved to file." << std::endl;
} else {
std::cerr << "Error opening file for writing." << std::endl;
}
// Retrieve the object from the file
Person p2;
std::ifstream ifs("person.txt");
if (ifs.is_open()) {
ifs >> p2;
ifs.close();
std::cout << "Person read from file:" << std::endl;
p2.display();
} else {
std::cerr << "Error opening file for reading." << std::endl;
}
return 0;
}
この例では、別の問題に遭遇します。このコードは車輪の再発明をしてタスクを達成しており、より多くのコード行、ひいてはより大きな複雑さをもたらしています。
しかし、追加の仕様を付けて同じクエリを投げかけた場合:
それができる最も有名なライブラリを使って、ファイルにオブジェクトを保存して取得するC++コードをください
この場合、回答はBoostライブラリを使用しています:
#include <iostream>
#include <fstream>
#include <vector>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
要約すると、AIを使ってC++コードを生成する際は、コンテキストの重要性を決して過小評価しないでください。それは関連する回答を得るための鍵です。したがって、クエリには細心の注意を払ってください。それが秘訣です!
