SQL 쿼리를 처리하는 클래스가 있습니다 (Qt 함수를 사용하지만 중요하지 않다고 생각합니다). 데이터를 쓰는 모든 쿼리는 다음과 같은 동일한 기본 프레임을 갖습니다.
bool Database::someSqlFunction(some variables)
{
if (! startTransaction()) {
return false;
}
QSqlQuery query(m_db);
try {
... Code using the passed variables and query ...
commitTransaction();
} catch (...) {
rollbackTransaction(query);
return false;
}
return true;
}
함수별로 정의 할 필요가 없도록이 코드를 재사용 할 수 있습니까? 다양한 코드를 포함하는 함수에 대한 포인터로 호출 할 함수를 사용하는 것에 대해 생각했지만 서명은 함수마다 다르므로 각 경우에 대해 오버로드 된 함수를 정의해야합니다. 또한 함수를 생성하기 위해 전처리기를 사용하는 것에 대해 생각했지만 인수의 수와 유형이 다른 동일한 문제입니다.
실행할 코드 블록을 다른 함수로 전달할 수 있습니까? 아니면 기능 템플릿을 통해 수행 할 수 있습니까?
편집 : 이것이 구현 될 수있는 방법은 다음과 같습니다.
헤더에서 :
template<typename SqlFunction>
bool writeHelper(SqlFunction sqlFunction)
{
if (! startTransaction()) {
return false;
}
QSqlQuery query(m_db);
try {
sqlFunction(query);
commitTransaction();
} catch (...) {
rollbackTransaction(query);
return false;
}
return true;
}
그리고 그것을 사용하는 예제 함수 :
bool Database::registerPlayers(const QString &name, int markerId)
{
return writeHelper([&](QSqlQuery &query) {
queryPrepare(query, QStringLiteral("INSERT INTO players(id, name, marker) "
"VALUES(NULL, ?, ?)"));
query.bindValue(0, name);
query.bindValue(1, markerId != 0 ? markerId : SQLITE_NULL);
queryExec(query);
});
}
편집 2 : 템플릿 없이도 동일한 작업을 수행 할 수 있습니다.
를 사용 std::function
하면 실제 함수에 정의 된 람다를 템플릿을 사용하지 않고도 간단히 전달할 수 있습니다. 도우미 함수의 구현은 다음과 같습니다.
bool Database::writeHelper(std::function<void(QSqlQuery &query)> sqlFunction)
{
if (! startTransaction()) {
return false;
}
QSqlQuery query(m_db);
try {
sqlFunction(query);
commitTransaction();
} catch (...) {
rollbackTransaction(query);
return false;
}
return true;
}
어쨌든,이 경우 컴파일러는 필요한 함수를 빌드 타임에 생성하고 최적화 할 수있는 반면에 std :: function 접근 방식을 사용하여 실제로 수행 될 작업을 알지 못하므로 템플릿 접근 방식을 사용하는 것이 분명히 더 좋습니다. 호출은 런타임에 발생합니다.
Lambda 클로저가 필요한 것 같습니다.
https://en.cppreference.com/w/cpp/language/lambda
예를 들어, 일반 알고리즘은 사용 사례와 매우 유사합니다. 변경되지 않는 공통 알고리즘과 호출시 자유롭게 제공 할 수있는 일부 작은 부분입니다.
https://en.cppreference.com/w/cpp/header/algorithm
예상되는 내용에 대한 정확한 세부 정보를 알지 못한 채 여기에 간단한 예를 제공합니다.
#include <iostream>
template<typename Fnct>
void
common_part(Fnct fnct)
{
std::cout << "begin common part\n";
for(auto i=0; i<3; ++i)
{
std::cout << "iteration " << i << " of common part\n";
fnct(i);
}
std::cout << "end common part\n";
}
void
specific_function_A()
{
common_part(
[&](const auto &n)
{
std::cout << "specific part A: " << n << '\n';
});
}
void
specific_function_B(int something_else)
{
common_part(
[&](const auto &n)
{
std::cout << "specific part B: " << n+something_else << '\n';
something_else*=2;
});
}
int
main()
{
specific_function_A();
std::cout << "~~~~~~~~\n";
specific_function_B(100);
return 0;
}
람다 클로저의 서명이 항상 동일하더라도 캡처는 추가 매개 변수를 제공하는 해결 방법으로 볼 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다