0

I searched to see if I find a solution to this problem but I was not able to see an answer. The problem that I'm having is while my code compiles, I don't get intellisense

if I'm receiving a parameter (or declaring a variable) such as this with template T :

unique_ptr<vector<unique_ptr<T>>> & dataSets;

intellisense finds dataSets.get() but it does not find dataSets.get()->clear(); however, it compiles fine if I do it. However, if it not a template, it seems to work fine.

CODE:

    template <typename T> 
void mtsql::MTMySQL<T>::executePrepareStatement(const string & sqlText,const unique_ptr<vector<SQLDataType>> & argList,unique_ptr<vector<unique_ptr<T>>> & dataSets)
{
    dataSets.get()->clear();
    unique_ptr<sql::ResultSet> rs;
    for (auto iter = argList->cbegin(); iter != argList->cend() ; ++iter)
    {
        auto ps = this->createPreparedStatment(sqlText,args);
        rs.reset(ps->execute());
        dataSets.get()->insert(std::move(rs)); 
        ps.release();
    }

}

I'm new at c++11 so I may be doing extra steps or steps that may be wrong (for example, I think ps.release() is not needed... my point was to delete it, but since is a smart point)

Thanks for the help!

EDIT 1: Thanks to the help, my code looks much nicer and without possible leakage. Thank you!

    dataSets->clear();

for (auto iter = argList->cbegin(); iter != argList->cend() ; ++iter)
{
    auto ps = this->createPreparedStatment(sqlText,args);
    dataSets->push_back(std::move(rs));         
}
ildjarn
  • 62,044
  • 9
  • 127
  • 211
Blues76
  • 133
  • 1
  • 2
  • 10
  • A a side note, you shouldn't have to do `dataSets.get()->clear()`, but simply `dataSets->clear()`, as `unique_ptr` implements `operator ->()`. It doesn't impact functionality, just readability. – Dave S Jul 13 '12 at 18:04
  • 1
    And, assuming `ps` is some sort of unique_ptr, you might have a memory leak when you execute `ps.release()`, since that function tells unique_ptr to release control to the caller and will not call the destructor. – Dave S Jul 13 '12 at 18:06

2 Answers2

2

C++ is not a simple language to parse and semantic. Therefore you can't expect IntelliSense to work perfectly with complicated types.

As for your code, you could simplify the code to do:

dataSets->clear();  // no need to use `get` here.

for (auto& ignored : *argList) {  // use range-based for.
    auto ps = this->createPreparedStatment(sqlText,args);
    dataSets->insert(ps->execute());  // no need to define 'rs'.
    // no need to release explicitly, if they are indeed smart pointers.
}

(And if dataSets is really a unique_ptr<vector<unique_ptr<T>>> I think you should use dataSets->push_back instead of insert.)


Edit: MSVC 2010 does not support range-based for. It does support lambdas though:

std::for_each(argList->cbegin(), argList->cend(), [&](const vector<SQLDataType>&) {
   auto ps = this->createPreparedStatment(sqlText,args);
   dataSets->insert(ps->execute());  // no need to define 'rs'.
});
Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • thank you for your answer. for some reason, I don't think this is valid in vs 2010 for (auto& ignored : *argList). Thank you !!! – Blues76 Jul 13 '12 at 18:18
  • 1
    No, support for the range-for was added in Visual C++ 2012. Visual C++ 2010 does not support it. – James McNellis Jul 13 '12 at 18:22
2

IntelliSense for template parameters and dependent names in C++ is limited at best.

T can be any type. There is no way for IntelliSense to accurately compute a common set of operations that are valid for all actual types with which your template will be instantiated.

Note that this problem affects dependent types too, not just to T itself, because T or the templates that you instantiate with T (like std::vector<std::unique_ptr<T>> in your example) may be explicitly specialized and those explicit specializations may have different members than the primary template.

From usage, it appears that it makes a best effort attempt to build a completions list for dependent names in some cases, but one should not be too surprised if this list is incomplete, empty, or incorrect.

Concepts, a feature proposed for C++11 but eventually dropped from the specification, would probably enable far better IntelliSense for template parameters and possibly for many dependent names.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • This is a weakness in the C++ template systems that Concepts were aiming at solving by providing the set of usable operations on the type. With Concepts, IntelliSense could work in templated code :) – Matthieu M. Jul 13 '12 at 19:21