C ++ 17 Невозможно использовать std :: bind для создания std :: function - PullRequest
0 голосов
/ 18 мая 2018

У меня есть функция Register, которая принимает std::function<void(const uint8_t* data, size_t len)> в качестве параметра.Я хочу использовать функцию-член объекта в качестве цели.

Я нашел этот вопрос , согласно которому ответ должен использовать std::bind, чтобы связать первый первый аргумент (неявный указатель this) с фактическим указателем объекта, а затем использовать егов качестве аргумента std::function.

Однако это больше не работает ни в C ++ 11, ни в C ++ 14, ни в C ++ 17?

Рассмотрим следующую тестовую программу.

#include <iostream>
#include <cstdint>
#include <functional>

void Register(std::function<void(const uint8_t* data, size_t len)> func) {
    //Dummy - directly call into function
    func(nullptr, 0);
}

class TestClass {
public:
    void TestRegister() {
         Register(
                 std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
         );
    }

    void TestTarget(const uint8_t* data, size_t len) {
        (void) data;
        (void) len;
        std::cout << "Hello there" << std::endl;
    }
};


int main() {
    TestClass testObj;
    testObj.TestRegister();
    return 0;
}

При компиляции для -std=c++17 это выдает довольно загадочное сообщение об ошибке (я понятия не имею, что здесь пытается сказать с помощью Wrong number of arguments for pointer-to-member):

In file included from /home/max/Documents/TestingFunctions/main.cpp:3:0:
/usr/include/c++/7/functional: In instantiation of ‘struct std::_Bind_check_arity<void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’:
/usr/include/c++/7/functional:854:12:   required from ‘struct std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’
/usr/include/c++/7/functional:875:5:   required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}]’
/home/max/Documents/TestingFunctions/main.cpp:14:78:   required from here
/usr/include/c++/7/functional:841:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
       static_assert(_Varargs::value
       ^~~~~~~~~~~~~
/home/max/Documents/TestingFunctions/main.cpp: In member function ‘void TestClass::TestRegister()’:
/home/max/Documents/TestingFunctions/main.cpp:14:26: error: could not convert ‘std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}; typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type = std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>](((TestClass*)this), std::placeholders::_1)’ from ‘std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>::type {aka std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>}’ to ‘std::function<void(const unsigned char*, long unsigned int)>’
                 std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
                 ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Замена *Функция 1022 * с функцией, которая делает то же самое в лямбда-выражении, компилируется и запускается без проблем.

void TestRegister() {
    Register(
            [this](const uint8_t* data, size_t len) {
                TestTarget(data, len);
            }
    );
}

Вопрос: Почему не работает подход std::bind из связанного вопроса?Эта функция была удалена или в моем коде есть ошибка?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Ваша функция принимает два параметра, а вы передаете только один заполнитель.

std::bind(&TestClass::TestTarget, this, std::placeholders::_1, std::placeholders::_2);
0 голосов
/ 18 мая 2018

Ваша функция Register ожидает функцию с двумя параметрами, но вы пытаетесь передать ей функцию с одним заполненным параметром.

void TestRegister() {
     Register(
             std::bind(&TestClass::TestTarget, this, std::placeholders::_1, std::placeholders::_2)
     );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...