samedi 19 novembre 2022

std::function Error : error: static assertion failed: Wrong number of arguments for pointer-to-member?

I have a tricky problem and I'm working on it for several hours but can't find a cause and solution of it. Hope someone help me.

I have to demonstrate function being called inside another function( pls see the comment in seminar.cpp)

Below are the files ( I have separated it into header and code files)

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;
}

seminar.h

#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

seminar.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

dist.h

namespace Nor
{

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

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

}

The above code and file structure works correctly and give me the correct expected output ie 50 100 Live here


Now I want to do more separation ie I want the implementation of drive function to move in another file ie in type.cpp

type.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

seminar.h

#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

seminar.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

Live here After doing this I am getting an below error:

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

Taking reference from this answer

I tried this way :

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

And Got this error:

/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);

See here live


I don't know correctly what I am doing wrong in moving the implementation of drive function can someone please help with implementing the corrrect way.

Note:: I'm fine if the solution uses another way to pass the function ie by not using std::function . Thanks

Aucun commentaire:

Enregistrer un commentaire