Есть ли способ сделать функцию доступной только в функции, переданной через аргумент в c ++? - PullRequest
0 голосов
/ 12 апреля 2020

Я хочу обрабатывать ошибки в моих функциях. Я решил сделать это с вызываемым аргументом в эту функцию. Поэтому, когда «пользователь» собирается вызвать эту «опасную» функцию, он может указать действие, которое необходимо выполнить, например, с помощью лямбда-выражения. Я хотел бы, чтобы пользователь мог вызывать определенную функцию внутри этой лямбды, которая недоступна в «области видимости пользователя» (она может быть доступна из некоторой другой скрытой области видимости, например, из того же пространства имен, что и у опасной функции, или даже лучшего пространства имен, вложенного в нее) Есть ли способ сделать такую ​​вещь?

Я мог бы попытаться передать его в качестве аргумента в lamda, но это требует от пользователя знать об этой функции. Еще хуже, если id нравится выставлять таким образом более одной функции.

Примерно так:

#include "dangerous.hpp"
int main() {
   std::string error_description
   // call a function from dangerous.hpp
   dngr::doathing(
      "param1", "param2", "param3",
      [&error_description](int error_code){
         error_description = get_description(error_code);
         //                    ^
         // also provided by dangerous.hpp somehow
      }
   );


   return 0;
}

но функции get_description () нигде не видно (не оглядываясь слишком много) определен не в пространстве имен по умолчанию

1 Ответ

0 голосов
/ 12 апреля 2020

Идиома пароля может помочь:

Сначала создайте структуру без конструктора publi c и сделайте ее другом одного из ваших классов.

class Key
{
private: // All private
    friend class MyClass; // only MyClass can use it.

    Key() {}

    Key(const Key&) = delete;
    Key& operator=(const Key&) = delete;
};

Теперь объявите ваша функция для защиты с этим аргументом:

void reset_password(const Key&, std::string);
std::string get_description(const Key&, int error_code);

Затем ваш класс может запросить соответствующий функтор:

class MyClass
{
public:

    void doathing(
        std::string param1, std::string param2, std::string param3,
        std::function<void(const Key&, int)> func)
    {
        // ...
        auto error_code = 42;
        func({}, error_code);
    }
};

И в main():

int main()
{
    MyClass c;
    std::string error_description;
    c.doathing(
        "param1", "param2", "param3",
        [&error_description](const Key& key, int error_code){
            error_description = get_description(key, error_code);
        }
    );
    std::cout << error_description;
    // get_description({}, 42); // error: 'Key::Key()' is private within this context
}

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...