4

I'm working on code for a container that stores strings and sorts them in alphabetical order (thought that it'd be a fun idea). I've been attempting to put a "[]" operator and assign it to the private member words so I can access any data or strings inside of said member. However, I've been struggling with this continuous error that I'm having trouble fixing. It says:

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

Here's some of the code regarding the error (Error is present at 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
}
//...

Another thing to note is that if I remove the brackets with st, the error is gone (Obviously not what I'm trying to achieve). Any help or a fix to this code would be greatly appreciated.

asked Jul 10, 2019 at 0:39
4
  • 2
    "Obviously not what I'm trying to achieve" What are you trying to achieve? That might be useful information for us to actually help you. Commented Jul 10, 2019 at 0:45
  • 4
    words is std::shared_ptr<std::vector<std::string>>. Why would you expect an operator[] for it to ALSO produce a std::shared_ptr<std::vector<std::string>>?? More conventional usage of operator[] is to produce an element of a container e.g. std::string::operator[]() produces a (reference to) a char. Also, having a class member that is std::shared_ptr<std::vector<string>> is pointless - a member that is a simple std::vector<std::string> is correct - and less error prone. And a class named sort .... Bleegh! Commented Jul 10, 2019 at 0:50
  • I believe that it first is probably your compiler, or build or "operator" needs a value to at least hold, try something else. Sorry if it didn't work M8 good luck. Commented Jul 10, 2019 at 0:51
  • Nitpick: "Retarded" is either an out-of-date medical term, or a technical chemical engineering term. You're not retarded, just ignorant. And hey, now you've learned! Also, if you want to post your own answer, you can do that -- you don't need to edit your question to contain the answer. Commented Jul 10, 2019 at 2:47

2 Answers 2

2

Your words member is not an array or container. It is a std::shared_ptr, which does not have an operator[] defined prior to C++17 (and even then, your code would still be using it wrong). That is why your operator[] fails to compile.

You have a std::shared_ptr pointing to a std::vector<std::string> object stored somewhere else in memory 1. If you want your operator[] to access the std::string values in that std::vector, you need to deference the pointer first in order to access the std::vector, and then you can call its operator[]. You need to fix the return value of your operator[] to be a single std::string, not a std::shared_ptr.

1: why are you using a pointer at all? Why not declare words to be an actual std::vector object directly in your class? std::vector<std::string> words;

Try this instead:

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];
}
//...
answered Jul 10, 2019 at 2:01
Sign up to request clarification or add additional context in comments.

1 Comment

Sigh. +1 for catching that the function prototype needs to be changed too. I missed that completely. Can't believe I did.
2

The problem is probably the fact that words is a std::shared_ptr, not an std::vector. std::shared_ptr::operator[]() is a C++17 thing (meaning it won't compile in C++11), and even then it doesn't do what you think it does:

Return value

A reference to the idx-th element of the array, i.e., get()[idx]

Then, from get()'s documentation:

std::shared_ptr::get

T* get() const noexcept; (until C++17)

element_type* get() const noexcept; (since C++17)

Meaning that get() returns a pointer. Together, this effectively makes your code the same as:

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

That is not what is appears you want. This is basically the functional equivalent of accessing the indexth element of an array of vectors (it's more complicated than that, but I don't know enough about the technical differences between pointers and arrays to articulate it properly here). What you want is the operator[]() of the dereferenced pointer like this:

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

What this boils down to is this: what you (probably) want is std::shared_ptr's dereference operator:

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

That should compile and do what you want.

Edit: It has come to my attention, thanks to Remy Lebeau's answer, that your function prototype will need to change as well, as (*words)[st] is not a std::shared_ptr<std::vector<std::string>>, it is merely as std::string. Thus, change the prototype to this instead:

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

And in the cpp:

std::string& sort::operator[](size_t st) 
{
 return (*words)[st];
}
answered Jul 10, 2019 at 1:58

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.