stl: не удаётся сделать emplace_back в вектор

103
07 декабря 2021, 15:20

Подскажите в чем может быть проблема:

Есть класс

class CSLE
{
public:
    // конструкторы
    CSLE(
        const int                           variablesAmount,    // кол-во неизвестных
        const borders_list_t&               variablesLimits,    // диапазон значений неизвестных
        const borders_list_t&               parametersLimits,   // диапазон значений коэффициентов
        const std::vector<std::string>&     variablesNames      // названия переменных
    );
};
// конструктор класса
CSLE::CSLE
(
    const int                           variablesAmount,    // кол-во неизвестных
    const borders_list_t&               variablesLimits,    // диапазон значений неизвестных
    const borders_list_t&               parametersLimits,   // диапазон значений коэффициентов
    const std::vector<std::string>&     variablesNames      // названия переменных
)
{
// тут формирую значения членов класса
}

Когда пытаюсь записать в вектор через

using sle_t = std::vector<CSLE>;
sle_t sleList;
sleList.emplace_back(2, { borders_t(-7, 7) }, { borders_t(-10, 10), }, variablesName[0]);

Получаю

Error C2672 'std::vector>::emplace_back': no matching overloaded function found
Error C2784 'decltype(auto) std::vector>::emplace_back(_Valty &&...)': could not deduce template argument for '_Valty &&...' from 'initializer list'

Когда делаю с указанием класса (как при push_back), то естественно всё нормально.

Думал, что при emplace_back просто не надо указывать соответствующий класс и все

Answer 1

Что делать?

Использовать push_back с фигурными скобками:

sleList.push_back({2, { borders_t(-7, 7) }, { borders_t(-10, 10), }, variablesName[0]});

Почему emplace_back не работает?

Простой пример:

struct A
{
    int x, y;
    A(int x, int y) : x(x), y(y) {}
};
void foo(A) {}
int main()
{
    foo(A(1,2)); // работает
    foo({1,2}); // работает
}

Примерно так работает push_back. Тут все нормально.

А emplace_back - это шаблон. Сделаем foo шаблоном и посмотрим на результат:

template <typename T>
void foo(T) {}
int main()
{
    foo<A>({1,2}); // работает, T = A (указан явно)
    foo(A(1,2)); // работает, T = A (компилятор догадался по аргументу функции)
    foo({1,2}); // не работает, T = ???
}

Вот что пишет Clang:

main.cpp:14:5: error: no matching function for call to 'foo'
    foo({1,2}); // не работает, T = ???
    ^~~
main.cpp:8:6: note: candidate template ignored: couldn't infer template argument 'T'
void foo(T) {}
     ^

Вызов foo({1,2}) для шаблонного foo не работает, потому что компилятор не может определить тип T.

Он никак не может догадаться, что под {1,2} вы имели в виду A.

С emplace_back происходит то же самое, (из-за того, что у вас некоторые аргументы имеют вид { ... }):

sleList.emplace_back(2, { borders_t(-7, 7) }, { borders_t(-10, 10), }, variablesName[0]);
//                      ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^

Перед фигурными скобками нужно указать тип: borders_list_t{ borders_t(-7, 7) } и т.д.

READ ALSO
Не вызывается функция closeEvent() в Qt

Не вызывается функция closeEvent() в Qt

Довольно простая ситуация - мне нужно просто вызвать диалоговое окно при любой попытке закрыть приложение пользователемВ документации написано,...

254
Запуск потока из абстрактного базового класса [дубликат]

Запуск потока из абстрактного базового класса [дубликат]

Нужно что бы конструктор абстрактного базового класса запускал в отдельном потоке чисто виртуальный метод, определённый дочерним классомЧто-то...

75
Ошибка линковки проекта c++

Ошибка линковки проекта c++

Писал программу для перевода чисел из DEC в HEX и наоборот разными функциями на Windows с помощью MVS, теперь пришла пора перенести программу на линукс,...

101
Отображает непонятные символы c++

Отображает непонятные символы c++

Пытаюсь сделать поиск участников из существующего файла, но отображает изначально непонятные цифры, в следствии чего как я подозреваю не дает...

76