Как вызвать конструктор как функцию?

Я пытаюсь создать временный объект С++ для того же быстрого вызова в конструкторе и ничего больше.

Почему-то это не работает

Вот код:

typedef std::vector<std::string> string_vec_t;

//-------------------------------------------------------------------------
struct visit_items
{
    virtual void action(std::string *s) = 0;
};

void items_visitor(visit_items *v)
{
    string_vec_t l = { "1", "2", "3", "4" };
    for (auto &s: l)
        v->action(&s);
}

struct my_visit_items: visit_items
{
public:
    string_vec_t *r;
    my_visit_items(string_vec_t *r /*, int */): r(r)
    {
        items_visitor(this);
    }

    virtual void action(std::string *s) override
    {
        r->push_back(*s);
        printf("visited: %s\n", s->c_str());
    }
};

//-------------------------------------------------------------------------
int main(int argc)
{
    string_vec_t r;
    r.push_back("1");
    my_visit_items(&r /*, 0 */);

    return -1;
}

Если у меня есть ctor дополнительный аргумент, то нет проблем. Но в нынешнем виде это не работает, и я не понимаю ошибки:

1>error C2040: 'r': 'my_visit_items &' differs in levels of indirection from 'string_vec_t'
1>error C2530: 'r': references must be initialized

Почему бы вам не написать функцию?

Ulrich Eckhardt 08.04.2019 21:54

Звоня do_this(&r);, вы передаете string_vec_t*, а не string_vec_t&

Gnawme 08.04.2019 21:56
do_this(r); за вызов эталонной версии. Удалить адрес оператора.
Raindrop7 08.04.2019 21:57

Прошу прощения, пример неверный. ``` struct do_this: do_what { public: string_vec_t *r; do_this(string_vec_t *r): r(r) { } virtual void action() override { } }; ```

BenS 08.04.2019 21:59

@BenS Если это неправильно, отредактируйте вопрос, а не просто оставляйте комментарий. Вы также должны уточнить, что именно вы подразумеваете под «по какой-то причине это не работает».

john 08.04.2019 22:04

Спасибо @john, я решил проблему. Я чувствую себя плохо из-за того, что не получил правильный код в первый раз, а затем получил отрицательный голос за что-то глупое.

BenS 08.04.2019 22:38

Строка "my_visit_items(&r /*, 0 */);" генерирует «ошибка: конфликтующее объявление ‘my_visit_items& r’». Это не то, что вы хотите сделать, но эту ошибку можно устранить с помощью «my_visit_items mvi(& r);»

2785528 08.04.2019 23:18

Ваше описание «создать временный объект C++ для того же быстрого вызова в конструкторе» и некоторые из ваших вариантов кодирования подсказывают мне, что вас может заинтересовать функтор... но в функторах, с которыми я знаком, ctor и dtor оба ничего не делают (что делает их очень быстрыми), а "operator()" выполняет все действия.

2785528 08.04.2019 23:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
8
108
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Когда вы хотите передать ссылку, вам нужно вызвать do_this(r); При вызове do_this(&r) вы передаете указатель на r.

Далее вы можете вызвать конструктор (теоретически) напрямую с помощью do_this::do_this(r);

Но почему бы не использовать функцию, если вы хотите иметь функцию? Не каждый компилятор допускает это без явной установки некоторых параметров компилятора (например, gcc требует -fpersmissive). Если причина в том, что вы хотите реализовать свою функцию только один раз, то вызовите функцию из конструктора.
Если вы хотите, чтобы функция была инкапсулирована в классе, не требуя атрибутов класса, вы также можете использовать функцию-член класса static.

Спасибо за ваш ответ, у меня был неправильный фрагмент кода, и я обновил его соответствующим образом. Пожалуйста, удалите свой ответ и мои комментарии, чтобы лучше отразить эту тему.

BenS 09.04.2019 00:16
Ответ принят как подходящий

my_visit_items(&r /*, 0 */); является объявлением my_visit_items ссылки r, как и my_visit_items &r;. Вместо этого попробуйте универсальную инициализацию. Вы также должны стараться избегать передачи указателей на строки и векторы. Код, который вы показали, будет нормально работать без указателей:

#include <iostream>
#include <vector>
#include <string>

typedef std::vector<std::string> string_vec_t;

//-------------------------------------------------------------------------
struct visit_items {
    virtual void action(const std::string& s) = 0;
    virtual ~visit_items() = default;
};

void items_visitor(visit_items& v) {
    string_vec_t l = {"1", "2", "3", "4"};
    for(auto& s : l) v.action(s);
}

struct my_visit_items : visit_items {
    string_vec_t& r;
    my_visit_items(string_vec_t& r) :
        visit_items{},
        r(r)
    {
        items_visitor(*this);
    }

    virtual void action(const std::string& s) override {
        r.push_back(s);
        std::cout << "Visited: " << s << "\n";
    }
};

//-------------------------------------------------------------------------
int main() {
    string_vec_t r;
    r.push_back("1");
    my_visit_items{r};    //   { } instead of ( )

    return 1;
}

Спасибо, Тед. Вот в чем проблема!

BenS 09.04.2019 00:15

Не связано с ошибками.

В моем Linux g++-v7:

Если вы включите достаточно флагов компилятора, вы можете обнаружить, что компилятор предупреждает об этой структуре:

struct visit_items
{
    virtual void action(std::string *s) = 0;
};

с участием

// warning: ‘struct visit_items’ has virtual functions and 
// accessible non-virtual destructor [-Wnon-virtual-dtor]

Примечание. Это предупреждение вызывает 2 другие проблемы (где используется класс).

Все это проясняется, когда вы предоставляете виртуальный dtor по умолчанию

struct visit_items  
{
   virtual ~visit_items() = default;
   virtual void action(std::string *s) = 0;
};

Другие вопросы по теме