Google mock не может издеваться над методом с шаблонным аргументом

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

Интерфейс (удалены все неактуальные методы)

class iat_protocol
{
public:
    virtual void get_available_operators(etl::vector<network_operator, 5>&) = 0;
};

мой макет

class at_protocol_mock : public iat_protocol
{
public:
    MOCK_METHOD((void), get_available_operators, (etl::vector<network_operator, 5>&), (override));
};

Это приводит к

In file included from /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock-actions.h:145,
                 from /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock.h:57,
                 from ../tests/shared/hal/at/at_channel_tests.cpp:1: /home/bp/dev/unode/eclipse/unit_tests/tests/shared/hal/at/mocks/at_protocol_mock.hpp: In member function ‘testing::internal::MockSpec<void(etl::vector<iobox::hal::at::network_operator, 5>&)> iobox::hal::at_protocol_mock::gmock_get_available_operators(const testing::internal::WithoutMatchers&, testing::internal::Function<void(etl::vector<iobox::hal::at::network_operator, 5>&)>*) const’: /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/gmock-function-mocker.h:343:74: error: invalid combination of multiple type-specifiers   343 |   typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
      |                                                                          ^~~~ /home/bp/dev/unode/eclipse/thirdparty/googletest/googlemock/include/gmock/internal/gmock-pp.h:17:31: note: in definition of macro ‘GMOCK_PP_IDENTITY’

Моих навыков работы с C++ недостаточно, чтобы понять, что компилятор пытается мне сказать.

Кто может мне помочь ?

Странный. Нет ничего необычного в насмешливых методах, которые принимают параметры шаблона (если сам метод не является шаблоном), я могу сделать это с помощью std::vector, например: godbolt.org/z/xPqrMYesT. Ошибка, кажется, указывает на метапрограммирование внутри GoogleTest, но я не могу сказать, является ли это ошибкой в ​​​​вашем коде или в библиотеке.

Yksisarvinen 19.03.2022 15:03

Привет @Yksisarvinen, спасибо за усилия. Тогда я буду исследовать дальше. Должен быть в моем коде. Приятно осознавать, что это должно быть возможно. Спасибо!

bas 19.03.2022 18:31

Вы пробовали так? MOCK_METHOD(void, get_available_operators, (etl::vector<network_operator, 5>&), (override));

Elvis Oric 19.03.2022 21:16

@ElvisOric без разницы, та же история

bas 19.03.2022 21:18

@Yksisarvinen, не могли бы вы снова попробовать свой пример с std::array с двумя аргументами шаблона. Это не удастся. Есть идеи, почему? Это ограничение Google mock? Есть ли обходной путь?

bas 19.03.2022 21:18

@bas А, интересно. В GoogleMock 1.10, который находится на godbolt, внезапно появилось четкое сообщение об ошибке: static assertion failed: This method does not take 2 arguments. Parenthesize all types with unproctected commas.godbolt.org/z/fjEc59cv6. И это действительно работает, когда вы добавляете еще один набор круглых скобок вокруг типа: godbolt.org/z/j5889TrKE

Yksisarvinen 19.03.2022 21:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
47
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Что ж, это странно, но простой using решает вашу проблему.

#include "gmock/gmock.h"

struct network_operator {};

namespace etl {
template <typename T, unsigned N>
struct vector {};
}  // namespace etl

using vector_5 = etl::vector<network_operator, 5>;

class iat_protocol {
   public:
    virtual void get_available_operators(vector_5&) = 0;
};

class at_protocol_mock : public iat_protocol {
   public:
    MOCK_METHOD(void, get_available_operators,
                (vector_5&),(override));
};

Из кулинарной книги gMock Работа с незащищенными запятыми

А, должно быть, это та же самая причина, на которую только что указал Иксисарвинен. Таким образом, макетный макрос Google может понять это. Также очень элегантный способ исправить это. Спасибо

bas 19.03.2022 21:33

Да, вы избавляетесь от запятых в имени типа, так что это также решает проблему. Хороший улов!

Yksisarvinen 19.03.2022 21:39

Последняя библиотека gmock показывает более наглядную информацию:

error: static_assert failed due to requirement '::testing::tuple_size<std::tuple<etl::vector<network_operator, 5> &>>::value == 2' "This method does not take 2 arguments. Parenthesize all types with unproctected commas."
    MOCK_METHOD(void, get_available_operators,

Parenthesize all types with unproctected commas.

Другое решение без using

#include "gmock/gmock.h"

struct network_operator {};

namespace etl {
template <typename T, unsigned N>
struct vector {};
}  // namespace etl

using vector_5 = etl::vector<network_operator, 5>;

class iat_protocol {
   public:
    virtual void get_available_operators(etl::vector<network_operator, 5>&) = 0;
};

class at_protocol_mock : public iat_protocol {
   public:
    MOCK_METHOD(void, get_available_operators,
                ((etl::vector<network_operator, 5>&)), (override));
//               ^                                 ^  
};

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