Std::function Ошибка: ошибка: статическое утверждение не удалось: неправильное количество аргументов для указателя на член?

У меня есть сложная проблема, и я работаю над ней несколько часов, но не могу найти причину и решение. Надеюсь, кто-нибудь поможет мне.

Мне нужно продемонстрировать, что функция вызывается внутри другой функции (пожалуйста, смотрите комментарий в семинаре.cpp)

Ниже приведены файлы (я разделил их на заголовочные файлы и файлы кода)

main.cpp

#include <iostream>
#include <functional>
#include "seminar.h"

int main()
{
    Tom::Car::Car car;
    Nor::Driving drivingnow;
    std::vector<uint8_t> X = car.road(drivingnow);
    for(int i = 0 ; i < X.size() ; i++){
        std::cout<<unsigned(X[i])<<" ";
    }

    return 0;
}

семинар.ч

#pragma once
#include "dist.h"
#include <vector>
#include <bits/stdc++.h>
namespace Tom
{
    namespace Car
    {

        class Car
        {
        public:
            std::vector<uint8_t> road(Nor::Driving &driving);
            
        };
    } // namespace Car
} // namespace Tom

семинар.cpp

#include "seminar.h"
#include <algorithm>
#include <functional>

namespace Tom
{
    namespace Car
    {
        std::vector<uint8_t> drive(Nor::Range &range)
        {
            std::vector<uint8_t> s;
            s.push_back(range.z);
            s.push_back(range.zz);
            return s;
        }

        template <typename T, typename B, typename L>
        std::vector<uint8_t> Content(T Sec, B Byte, L Func)
        {
            Nor::Range Rom;
            std::vector<uint8_t> z = Func(Rom);
            return z;
        }

        std::vector<uint8_t> Car::road(Nor::Driving &driving)
        {
            std::function<std::vector<uint8_t>(Nor::Range &)> Func = &drive;

            return Content(driving, 1, Func);  // passing drive function into content
        }

    } // namespace Car
} // namespace Tom

расст.ч

namespace Nor
{

class Driving{
public:
  int x = 1;
};

class Range{
public:
  int z = 50;
  int zz = 100;
};

}

Приведенный выше код и файловая структура работают правильно и дают мне правильный ожидаемый результат, т.е. 50 100 Жить здесь


Теперь я хочу сделать больше разделения, то есть я хочу, чтобы реализация функции drive переместилась в другой файл, то есть в type.cpp

тип.cpp

#include <algorithm>
#include "seminar.h"

#include <functional>

namespace Tom
{
    namespace Car

    {
        std::vector<uint8_t> Car::drive(Nor::Range &range)
        {
            std::vector<uint8_t> s;
            s.push_back(range.z);
            return s;
        }

    } // namespace Car
} // namespace Tom

семинар.ч

#pragma once
#include "dist.h"
#include <vector>
#include <bits/stdc++.h>
namespace Tom
{
    namespace Car
    {

        class Car
        {
        public:
            std::vector<uint8_t> road(Nor::Driving &driving);
            std::vector<uint8_t> drive(Nor::Range &range);
        };
    } // namespace Car
} // namespace Tom

семинар.cpp

#include "seminar.h"
#include <algorithm>

#include <functional>

namespace Tom
{
    namespace Car
    {
        

        template <typename T, typename B, typename L>
        std::vector<uint8_t> Content(T Sec, B Byte, L Func)
        {
            Nor::Range Rom;
            std::vector<uint8_t> z = Func(Rom);
            return z;
        }

        std::vector<uint8_t> Car::road(Nor::Driving &driving)
        {
            std::function<std::vector<uint8_t>(Nor::Range &)> Func = &drive;

            return Content(driving, 1, Func);
        }

    } // namespace Car
} // namespace Tom

Жить здесь После этого я получаю следующую ошибку:

seminar.cpp: In member function ‘std::vector<unsigned char> Tom::Car::Car::road(Nor::Driving&)’:
seminar.cpp:22:71: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say ‘&Tom::Car::Car::drive’ [-fpermissive]
   22 |             std::function<std::vector<uint8_t>(Nor::Range &)> Func = &drive;
      |                                                                       ^~~~~
seminar.cpp:22:71: error: conversion from ‘std::vector (Tom::Car::Car::*)(Nor::Range&)’ to non-scalar type ‘std::function(Nor::Range&)>’ requested

Со ссылкой на этот ответ

Я пробовал так:

std::function<std::vector<uint8_t>(Nor::Range)> f = std::bind(&Car::drive, this);

И получил эту ошибку:

/usr/include/c++/9/functional:775:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
  774 |       static_assert(_Varargs::value
      |                               ~~~~~
  775 |       ? sizeof...(_BoundArgs) >= _Arity::value + 1
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  776 |       : sizeof...(_BoundArgs) == _Arity::value + 1,
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
seminar.cpp: In member function ‘std::vector<unsigned char> Tom::Car::Car::road(Nor::Driving&)’:
seminar.cpp:23:73: error: conversion from ‘std::_Bind_helper (Tom::Car::Car::*)(Nor::Range&), Tom::Car::Car*>::type’ {aka ‘std::_Bind (Tom::Car::Car::*(Tom::Car::Car*))(Nor::Range&)>’} to non-scalar type ‘std::function(Nor::Range)>’ requested
   23 |            std::function<std::vector<uint8_t>(Nor::Range)> f = std::bind(&Car::drive, this);
      |                                                                ~~~~~~~~~^~~~~~~~~~~~~~~~~~~
seminar.cpp:25:40: error: ‘Func’ was not declared in this scope
   25 |             return Content(driving, 1, Func);

Смотрите здесь в прямом эфире


Я не знаю правильно, что я делаю неправильно при перемещении реализации функции drive, может кто-нибудь помочь с правильной реализацией.

Примечание: я не против, если в решении используется другой способ передачи функции, т. е. без использования std::function . Спасибо

У вас уже есть пространство имен Car, вы действительно хотите class Car с методом (который должен быть статическим)?

Jarod42 19.11.2022 15:08

Как показано, методы участника могут быть static (один из способов решения вашей проблемы).

Jarod42 19.11.2022 15:17
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
2
85
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В семинаре.cpp, здесь:

std::function<std::vector<uint8_t>(Nor::Range &)> Func = &drive;

drive — это функция-член. Для вызова требуется указатель this.

Вы можете легко решить это, обернув его в лямбду:

std::function<std::vector<uint8_t>(Nor::Range &)> Func = [this](Nor::Range & r) {
    return this->drive(r);
};

Если вы предпочитаете метод std::bind, который вы пробовали, вам нужен заполнитель для параметра Nor::Range&:

std::function<std::vector<uint8_t>(Nor::Range &)> Func = std::bind(&Car::drive, this, std::placeholders::_1);

Кроме того, вам вообще не нужна std::function, так как это локальная переменная, которую вы сразу же передаете другой функции, поэтому просто используйте вместо нее auto (или передайте ее напрямую без промежуточной переменной):

auto Func = [this](Nor::Range & r) {
    return this->drive(r);
};

Вы также можете просто передать лямбду напрямую (поскольку OP не требуется для использования std::function).

john 19.11.2022 15:15

Создание функции-члена static — еще одна возможность.

Jarod42 19.11.2022 15:28

@ Jarod42 Конечно, но это изменение дизайна, и это далеко не единственное изменение, которое я бы внес в код OP. Предположительно, это не настоящий код, а неловко упрощенная версия.

Nelfeal 19.11.2022 15:35

Указатели нестатических функций-членов должны быть инициализированы следующим образом:

return_type (class_name::*pointer_name)(argument_types ...) = &class_name::function_name;

Их следует называть так:

(instance_name.*pointer_name)(arguments ...);

Такие указатели можно назначать объектам std::function, что немного сложно. Следует обратить внимание, что this является неявным аргументом в функции-члене, поэтому тип указателя класса должен быть явно объявлен как аргумент в шаблоне объекта std::function в таком присваивании. Например,

std::function<std::vector<uint8_t>(Car *, Nor::Range &)> Func = &Car::drive;

Вы также упомянули функцию std::bind. В этом случае вы должны использовать std::placeholders, чтобы оставить место для неопределенных аргументов. Обратите внимание, что шаблон объекта std::function должен содержать только неопределенные аргументы.

std::function<std::vector<uint8_t>(Nor::Range &)> Func = std::bind(&Car::drive, this, std::placeholders::_1);

Вы можете попробовать auto:

auto Func = std::bind(&Car::drive, this, std::placeholders::_1);

std::placeholders::_1 позволяет передать аргумент Nor::Range &range функции Car::drive позже. Неявный аргумент this также должен явно использоваться в функции std::bind.

Извините, есть одна ошибка. Функция bind может быть назначена объектам function, хотя она не возвращает объект function. Но я думаю, что гораздо удобнее использовать auto.

Shuangcheng Ni 19.11.2022 16:03

"они не могут быть назначены function объектам" - false.

Nelfeal 19.11.2022 17:14

Большое спасибо, что указали на мою ошибку. Я забыл включить указатель объекта в качестве параметра здесь.

Shuangcheng Ni 19.11.2022 17:51

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