Ошибка компилятора с gmock и boost::signals2

#c #boost #googlemock

#c #повышение #googlemock

Вопрос:

Я извлек код, который больше не компилируется. С boost 1.70 и gmock 1.7.2 код компилируется без каких-либо ошибок, но с более новыми библиотеками boost 1.72 и gmock 1.10 он больше не компилируется. Приведенная ниже ошибка довольно загадочна.

Любая помощь очень ценится.

 #include <boost/signals2.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

using ::testing::Return;
using ::testing::_; // Matcher for parameters

class M{
public:
    MOCK_METHOD1(connect, boost::signals2::connection(boost::signals2::signal<void(int)>::slot_type slot));
};

TEST(A,B){
    M m;

    ON_CALL(m, connect(_)).WillByDefault(Return(boost::signals2::connection{}));
}

int main(){
    return 0;
}
 

Вот выходные данные компилятора:

 In file included from /home/xxx/mycode2/google-googletest/examples/test/main.cpp:1:
In file included from /home/xxx/my/boost_1_72_0/include/boost/signals2.hpp:19:
In file included from /home/xxx/my/boost_1_72_0/include/boost/signals2/signal.hpp:22:
In file included from /home/xxx/my/boost_1_72_0/include/boost/signals2/connection.hpp:24:
In file included from /home/xxx/my/boost_1_72_0/include/boost/signals2/slot.hpp:30:
In file included from /home/xxx/my/boost_1_72_0/include/boost/signals2/variadic_slot.hpp:24:
/home/xxx/my/boost_1_72_0/include/boost/signals2/detail/slot_template.hpp:160:26: error: call to implicitly-deleted copy constructor of 'std::tuple<boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;>'
        _slot_function = detail::get_invocable_slot(f, detail::tag_type(f));
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/xxx/my/boost_1_72_0/include/boost/signals2/detail/slot_template.hpp:85:9: note: in instantiation of function template specialization 'boost::signals2::slot<void (int), boost::function<void (int)> >::init_slot_function<std::tuple<boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;> >' requested here
        init_slot_function(f);
        ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:133:4: note: in instantiation of function template specialization 'boost::signals2::slot<void (int), boost::function<void (int)> >::slot<std::tuple<boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;> >' requested here
        : _M_head_impl(std::forward<_UHead>(__h)) { }
          ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/bits/std_function.h:285:9: note: in instantiation of function template specialization 'testing::Action<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>::ActionAdapter::operator()<boost::signals2::slot<void (int), boost::function<void (int)> > >' requested here
        return (*_Base::_M_get_pointer(__functor))(
               ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/bits/std_function.h:676:33: note: in instantiation of member function 'std::_Function_handler<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >), testing::Action<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>::ActionAdapter>::_M_invoke' requested here
            _M_invoker = amp;_My_handler::_M_invoke;
                                       ^
/home/xxx/my/googletest/install-release-1.10.0-508-g5a509dbd/include/gmock/gmock-actions.h:477:9: note: in instantiation of function template specialization 'std::function<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>::function<testing::Action<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>::ActionAdapter, void, void>' requested here
      : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
        ^
/home/xxx/my/googletest/install-release-1.10.0-508-g5a509dbd/include/gmock/gmock-actions.h:662:12: note: in instantiation of member function 'testing::Action<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>::Action' requested here
    return Action<F>(new Impl<R, F>(value_));
           ^
/home/xxx/mycode2/google-googletest/examples/test/main.cpp:16:42: note: in instantiation of function template specialization 'testing::internal::ReturnAction<boost::signals2::connection>::operator Action<boost::signals2::connection (boost::signals2::slot<void (int), boost::function<void (int)> >)>' requested here
    ON_CALL(m, connect(_)).WillByDefault(Return(boost::signals2::connection{}));
                                         ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:640:17: note: explicitly defaulted function was implicitly deleted here
      constexpr tuple(const tupleamp;) = defau<
                ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:523:19: note: copy constructor of 'tuple<boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;>' is implicitly deleted because base class '_Tuple_impl<0, boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;>' has a deleted copy constructor
    class tuple : public _Tuple_impl<0, _Elements...>
                  ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:351:17: note: explicitly defaulted function was implicitly deleted here
      constexpr _Tuple_impl(const _Tuple_implamp;) = defau<
                ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:327:7: note: copy constructor of '_Tuple_impl<0, boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;>' is implicitly deleted because base class '_Head_base<0UL, boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;>' has a deleted copy constructor
    : private _Head_base<_Idx, _Head>
      ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:128:17: note: explicitly defaulted function was implicitly deleted here
      constexpr _Head_base(const _Head_baseamp;) = defau<
                ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c  /9/tuple:165:13: note: copy constructor of '_Head_base<0, boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;, false>' is implicitly deleted because field '_M_head_impl' is of rvalue reference type 'boost::signals2::slot<void (int), boost::function<void (int)> > amp;amp;'
      _Head _M_head_impl;
            ^
/home/xxx/my/boost_1_72_0/include/boost/function/function_template.hpp:1119:21: note: passing argument to parameter 'f' here
  operator=(Functor f)
                    ^
1 error generated.
make[2]: *** [CMakeFiles/myapp.dir/build.make:63: CMakeFiles/myapp.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/myapp.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
 

Ответ №1:

Я могу заставить это работать

 #include <boost/signals2.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::_; // Matcher for parameters
using ::testing::Return;

struct M {
    MOCK_METHOD1(connect, boost::signals2::connection(boost::signals2::signal<void(int)>::slot_type slot));
};

TEST(A, B) {
    M m;
    ON_CALL(m, connect(_)).WillByDefault(Return(boost::signals2::connection{}));
}
 

используя это CMakeLists.txt:

 project(stackoverflow)
cmake_minimum_required(VERSION 3.5)
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

set(Boost_NO_SYSTEM_PATHS On)
set(BOOST_ROOT "/home/sehe/custom/boost_1_74_0")
find_package(Boost COMPONENTS system REQUIRED)

#include(GoogleTest)
enable_testing()
find_package(GMock REQUIRED)

include_directories(${Boost_INCLUDE_DIR})
ADD_EXECUTABLE(sotest test.cpp)

target_link_libraries(sotest ${BOOST_system_LIBRARY_RELEASE})
target_link_libraries(sotest gmock_main)
#gtest_add_tests(sotest "" AUTO)
 

Который затем запускается с

 cmake .
cmake --build .
./sotest
 

Печать

введите описание изображения здесь

PS: Я удалил int amin(){} из вашей исходной программы, чтобы получить макет main

Кроме того, я проверил, что путь включения предназначен для Boost 1.74.0, проверив compile_command.json :

   "command": "/usr/bin/c     -I/home/sehe/custom/boost_1_74_0 -I/usr/src/googletest/googlemock/include -I/usr/src/googletest/googletest/include    -o CMakeFiles/sotest.dir/test.cpp.o -c /home/sehe/Projects/mockingbird/test.cpp",
 

Комментарии:

1. Ммм. Похоже, у меня gmock 1.8.0. Это может быть фактором

2. Спасибо за быстрый ответ. Я думаю, что это тест Google. Я разделяю пополам, и это плохая фиксация 9494c45e75a55547f3f183a1161fbd39d29b994e . Поэтому я изменил аргумент функции на std::function<void(int)> то, что она работает даже с gmock 1.10.

3. На случай, если это поможет вам сравнить, я предварительно M обработал объявление и вручную упростил полученную тарабарщину, используя typedefs. Если вы сделаете то же самое со своей версией кода, вы можете обнаружить, что больше не работает: gist.github.com/sehe/925b9f1b04df20efeef94072e52b5e21 (подтверждено, что он все еще работает после расширения)

4. Читая исходное сообщение об ошибке, похоже, что жалоба заключается в том, что std::tuple<F::ArgumentTuple> имеет удаленный конструктор копирования (что не относится ко мне). Однако это вообще НЕ проблема gmock, потому что задействованы только типы Boost и std.

5. Утверждение проходит и на моей машине. Если я проверю один коммит gmock перед вышеуказанным коммитом, он сработает, поэтому я думаю, что использование std::function для реализации стирания типов в действии, оборачивая устаревший ActionInterface, если это необходимо , все испортит. В любом случае спасибо за вашу помощь.