C ++ - Ошибка - ни один оператор "[]" не соответствует этим операндам - PullRequest
2 голосов
/ 10 июля 2019

Я работаю над кодом для контейнера, который хранит строки и сортирует их в алфавитном порядке (подумал, что это будет забавная идея).Я пытался поместить оператор «[]» и назначить его закрытому члену words , чтобы я мог получить доступ к любым данным или строкам внутри указанного члена.Тем не менее, я боролся с этой постоянной ошибкой, которую мне трудно исправить.Там написано:

No operator "[]" matches these operands. Operand types are std::shared_ptr<std::vector<std::string, std::allocator<std::string>>>[size_t]

Ниже приведен код ошибки (ошибка присутствует в class.cpp):

class.h

#pragma once

#include <memory>
#include <vector>
#include <string>
#include <iostream>


class sort
{
public:

//...


    sort(int i): words(std::make_shared<std::vector<std::string>>(i)) { } 

    std::shared_ptr<std::vector<std::string>> & operator [](size_t st);

//...

private:

    std::shared_ptr<std::vector<std::string>> words;
    std::string alpha = "abcdefghijklmnopqrstuvwxyz";

};

class.cpp

#include "sort.h"

#include <memory>
#include <vector>
#include <iostream>

//...

std::shared_ptr<std::vector<std::string>> & sort::operator[](size_t st) 
{

    return words[st]; //Error is defined at the brackets
}

//...

Еще один момент, на который следует обратить внимание: если я уберу скобки с st,ошибка ушла (очевидно, не то, что я пытаюсь достичь).Любая помощь или исправление этого кода будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Ваш words член не является массивом или контейнером.Это std::shared_ptr, у которого нет operator[], определенного до C ++ 17 (и даже тогда ваш код все равно будет использовать его неправильно).Вот почему ваш operator[] не может скомпилироваться.

У вас есть std::shared_ptr, указывающий на std::vector<std::string> объект, хранящийся где-то еще в памяти 1 .Если вы хотите, чтобы ваш operator[] имел доступ к std::string значениям в этом std::vector, вам необходимо сначала отложить указатель, чтобы получить доступ к std::vector, а затем вы можете вызвать его operator[].Вам необходимо зафиксировать возвращаемое значение вашего operator[], чтобы оно было единичным std::string, а не std::shared_ptr.

1: почему вы вообще используете указатель?Почему бы не объявить words фактическим std::vector объектом непосредственно в вашем классе?std::vector<std::string> words;

Попробуйте вместо этого:

class.h

#pragma once

#include <memory>
#include <vector>
#include <string>
#include <iostream>

class sort
{
public:

    //...

    std::string& operator [](size_t st);

    //...

private:

    std::shared_ptr<std::vector<std::string>> words;
    std::string alpha = "abcdefghijklmnopqrstuvwxyz";

};

class.cpp

#include "sort.h"

#include <memory>
#include <vector>
#include <iostream>

//...

std::string& sort::operator[](size_t st) 
{
    return (*words)[st];
}

//...
2 голосов
/ 10 июля 2019

Возможно, проблема в том, что words - это std::shared_ptr, а не std::vector.std::shared_ptr::operator[]() - это C ++ 17 (что означает, что он не будет компилироваться в C ++ 11), и даже тогда он не будет делать то, что вы думаете:

Возвращаемое значение

Ссылка на idx-й элемент массива, т. Е. Get () [idx]

Затем из * Документация 1018 * :

std :: shared_ptr :: get

T * get () const noexcept;(до C ++ 17)

element_type * get () const noexcept;(начиная с C ++ 17)

Это означает, что get() возвращает указатель.Вместе это делает ваш код таким же, как:

std::vector<int>* ptr = nullptr; // Note that this data is probably  allocated some how...
// Then, later...
ptr[index];

Это не то, что вам нужно.По сути, это функциональный эквивалент доступа к index -ому элементу массива векторов (это более сложно, но я не знаю достаточно о технических различиях между указателями и массивами, чтобы правильно сформулировать его здесь).То, что вы хотите, это operator[]() разыменованного указателя, например:

(*ptr)[index]; // Parenthesis for clarity. I don't think that they are technically necessary here.

То, что это сводится к следующему: то, что вы (вероятно) хотите, это оператор разыменования std::shared_ptr :

 return (*words)[st]; // again, parenthesis for clarity here.
                     // I don't think they are technically necessary here, either.

Это должно скомпилировать и делать то, что вы хотите.

Редактировать: Это привлекло мое внимание, благодаря Ответ Реми Лебо, что и прототип вашей функции нужно будет изменить, поскольку (*words)[st] - это не std::shared_ptr<std::vector<std::string>>, а просто std::string.Таким образом, вместо этого замените прототип:

std::string& operator [](size_t st);

И в cpp:

std::string& sort::operator[](size_t st) 
{
   return (*words)[st];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...