C ++에서 실행되고 다른 함수를 통해 전달되는 다양한 코드 블록으로 함수를 정의 할 수 있습니까?

Tobias Leupold

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 접근 방식을 사용하여 실제로 수행 될 작업을 알지 못하므로 템플릿 접근 방식을 사용하는 것이 분명히 더 좋습니다. 호출은 런타임에 발생합니다.

prog-fh

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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관