0

Eclipse IDE is throwing me an error on the following line that "method 'get' could not be resolved". The exact error message is

Method 'get' could not be resolved, Location: line xxx, Type: Semantic Error

The error line:

const TagValue* tagValue = ((*mktDataOptions)[i]).get();

What is going wrong here? This code was given to me as an API so presumably others have used it before. Similar errors appear about 8 other times in the code I was given and I have trouble believing it was coded wrong the same way 8 separate times.

Questions

Can someone parse this line for me and explain exactly what it is trying to do?
Why is my Eclipse throwing an error for all these instances and how can it be fixed?

Relevant Code

This line exists in the function:

void EClient::reqMktData(TickerId tickerId, const Contract& contract, 
const std::string& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions)
...
    if( m_serverVersion >= MIN_SERVER_VER_LINKING) {
        std::string mktDataOptionsStr("");
        const int mktDataOptionsCount = mktDataOptions.get() ? mktDataOptions->size() : 0;
...
                const TagValue* tagValue = ((*mktDataOptions)[i]).get();

Where "TagValueListSPtr" is defined in a header as

struct TagValue
{
    TagValue() {}
    TagValue(const std::string& p_tag, const std::string& p_value)
        : tag(p_tag), value(p_value)
    {}

    std::string tag;
    std::string value;
};

typedef shared_ptr<TagValue> TagValueSPtr;
typedef std::vector<TagValueSPtr> TagValueList;
typedef shared_ptr<TagValueList> TagValueListSPtr;

And "shared_ptr" is defined as

template<typename X> class shared_ptr {
public:

   typedef shared_ptr_defs::Use Use;

   template<typename Y> friend class shared_ptr;

   explicit shared_ptr(X* ptr = 0) : ptr_(ptr) {}

   ~shared_ptr() { if (use_.only()) delete ptr_; }

   template<typename Y>
   shared_ptr(const shared_ptr<Y>& other)
      : ptr_(other.ptr_),
        use_(other.use_)
      {}

   shared_ptr& operator=(const shared_ptr& other) {
      if ( &use_ == &other.use_ ) { return *this; }
      if ( use_.only() ) { delete ptr_; }
      use_ = other.use_;
      ptr_ = other.ptr_;
      return *this;
   }

   X& operator*()  const { return *ptr_; }
   X* operator->() const { return ptr_; }
   X* get()        const { return ptr_; }
   bool only() const { return use_.only(); }

   void reset(X* ptr = 0) {
      if ( use_.only() ) { delete ptr_; }
      ptr_ = ptr;
      use_ = Use();
   }

private:

   X *ptr_;
   Use use_;
};
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
mathjacks
  • 335
  • 2
  • 4
  • 11
  • Can you add the exact error message? This sounds like a linker error. – Daniel Jour Aug 11 '15 at 00:23
  • .... though `get` is inline, so this is probably not the issue. – Daniel Jour Aug 11 '15 at 00:25
  • 1
    `*` means to dereference the pointer. `*mktDataOptions` is the object being pointed to (which is a vector). `mktDataOptions` is the pointer. `(*mktDataOptions)[i]` accesses the `i`th member of the vector. – M.M Aug 11 '15 at 00:28
  • I have added the exact message from Eclipse at the top in a code block (please ignore the coloring). Not sure how helpful it is. – mathjacks Aug 11 '15 at 00:28
  • 1
    A lot ... this is an error message from eclipse, not the compiler. Having said that, does it compile? (And run?) – Daniel Jour Aug 11 '15 at 00:32
  • @DanielJour , yes, in fact this does compile. I should have mentioned this. Is this an Eclipse error I should feel free to ignore? I'd still like to get rid of it. – mathjacks Aug 11 '15 at 00:39

1 Answers1

1

Can someone parse this line for me and explain exactly what it is trying to do?

/* A pointer (to a const qualified TagValue) */
const TagValue*
/* named */ tagValue
/* is initialised to the result of */ = ((
/* dereferencing */ *
/* the shared pointer */ mktDataOptions)
/* which points to a vector */
/* and calling operator[] on it */ [i])
/* which returns the reference to */
/* a shared pointer to a TagValue */
/* whose */ .get();
/* member function is called, returning /*
/* as final result a pointer to a TagValue */

This is actually a pretty complex design, regarding ownership (there are a lot of shared pointers involved), which is why I doubt that this is actually needed, but well.

The mktDataOptions is a shared pointer to a vector containing shared pointers to TagValues. So to obtain a pointer to a TagValue you need to dereference the pointer to the vector with shared_ptr::operator*(), select an element (the ith) of that vector using its std::vector::operator[](). This is a shared pointer to a TagValue, so to get the underlying pointer the member function shared_ptr::get() is applied.

You could rewrite that to...

// using references, otherwise you make copies,
// which changes the meaning of the code.

// Get the vector from the shared pointer
std::vector<shared_ptr<TagValue>> & the_vector = *mktDataOptions;

// get a single element from it
shared_ptr<TagValue> const & the_element = the_vector[i];

// get it's underlying pointer
TagValue * the_pointer = the_element.get();

// it's a pointer to a non const TagValue, which can be
// converted to a pointer to a const TagValue (the type of the variable
// which gets initialised)
TagValue const * tagValue = the_pointer;

Why is my Eclipse throwing an error for all these instances and how can it be fixed?

[...] Is this an Eclipse error I should feel free to ignore? I'd still like to get rid of it.

From some research it seems to be an eclipse bug, that can be resolved by deleting workspace/.metadata, but I need to note that I'm not an eclipse user, so I cannot verify or recommend some possible solution.

In your case, I'd make a copy of the workspace and project directories, and then start experimenting with some suggestions from:

But judging from those questions, it seems like this is a relatively strange bug, so prepare for some frustration.

Community
  • 1
  • 1
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
  • Please reformat your answer so it is legible. Embedding it within comments does not qualify. – user207421 Aug 11 '15 at 01:48
  • @EJP Please read the whole answer: I embedded comments into the actual source code line in question, but also provided a textual description as well as equivalent, easier to understand code. – Daniel Jour Aug 11 '15 at 01:51
  • @Daniel Jour. This is incredibly helpful -- thank you. I should note that I am not tied to Eclipse. Is there a better option for working with large project APIs other than Eclipse IDE? Do people practically ever just do this in vim and compile with g++? Apologies for the questions -- this is one of my first bigger projects. – mathjacks Aug 11 '15 at 22:41
  • Glad that it helps you :) I'm doing my stuff with vim and sometimes Emacs, using makefiles to handle building etc. I personally dislike eclipse, but it seems to be a frequently used IDE. I guess for C++ projects makefiles or cmake are good, portable ways to build software, allowing one yo use whatever editor/IDE that suits best (including eclipse). (And of course, use some version control software, like git) – Daniel Jour Aug 12 '15 at 05:05