ARTICLE AD BOX
What you did with
#define SetValue push_backis purely a preprocessor trick: the compiler sees it after the macro expansion, but your IDE’s IntelliSense/code completion typically works on the AST before (or without fully trusting) macro-expanded “new member names”. So it’s not going to show SetValue in the vec. member list, because as far as the type system is concerned, std::vector simply doesn’t have a member called SetValue.
If you want something.SetValue(...) to behave like a real method (including dot-autocomplete), then SetValue has to be an actual member function of the type you’re using. Since you can’t add members to std::vector, the standard solution is: wrap it.
Wrap/derive and add the alias as a real member
#include <vector> #include <utility> template <class T> struct Vec : std::vector<T> { using std::vector<T>::vector; // inherit constructors void SetValue(const T& v) { this->push_back(v); } void SetValue(T&& v) { this->push_back(std::move(v)); } };Now use Vec<int> instead of std::vector<int> in your nested map:
#include <map> #include <string> std::map<std::string, std::map<std::string, std::map<int, Vec<int>>>> example; example["Stack"]["OverFlow"][3].SetValue(2); // completion shows SetValueIf you don’t care about dot-autocomplete
Then a free function works fine:
template<class T, class Alloc> void SetValue(std::vector<T, Alloc>& v, T value) { v.push_back(std::move(value)); }Usage:
SetValue(example["Stack"]["OverFlow"][3], 2);But that will never show up after vec. because it’s not a member.
So yeah: macros can’t create new members, and IntelliSense won’t list them as such. If you want vec.SetValue(...) to feel native, wrapping (or deriving) is the way to go.
