Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

In seminar.cpp, here:

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

drive is a member function. It needs the this pointer to be called.

You can easily solve this by wrapping it in a lambda:

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

If you prefer the std::bind method that you tried, you need a placeholder for the Nor::Range& parameter:

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

Also, you really don’t need the std::function at all since it’s a local variable that you immediately pass to another function, so just use auto instead (or pass it directly without an intermediate variable):

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

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading