Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::pair - Pointer yes/no?

56 views
Skip to first unread message

Heinz-Mario Frühbeis

unread,
May 25, 2016, 2:09:58 PM5/25/16
to
Hi,

here I have a template class with a vector:

template < class t_MapMember >
class c_IDAMap{
private:
typedef std::pair < std::string, t_MapMember > tPair;
typedef std::vector < tPair > tVec;
// ...
}

I'm using it e.g.:
class c_Member{
// ...
}
c_IDAMap <c_Member*> mMap; // with pointer

I also could use it like this:
c_IDAMap <c_Member> mMap; // w/o pointer

How can I get in c_IDAMap an info about the template if it is a pointer
or not?

Regards
Heinz-Mario Frühbeis

K. Frank

unread,
May 25, 2016, 9:00:44 PM5/25/16
to
Hello Heinz-Mario!
If I understand correctly, you are asking how to determine
whether or not the type t_MapMember is a pointer (in a specific
instantiation of c_IDAMap).

You could use std::is_pointer in type_traits. See, e.g.:

http://www.cplusplus.com/reference/type_traits/is_pointer/

To be concrete:

#include <iostream>
using std::cout;
using std::endl;

#include <type_traits>

template <typename T> class A {
public:
static bool isPointer() { return std::is_pointer<T>::value; }
private:
T t;
};

int main (int argc, char* argv[]) {
A<int> aInt;
A<int*> aPInt;
cout << "aInt.isPointer() = " << aInt.isPointer() << endl;
cout << "aPInt.isPointer() = " << aPInt.isPointer() << endl;
}

Here, class A is a baby version of your c_IDAMap. You can
tell whether type T (the analog of your t_MapMember) is a
pointer.

(My example might not be the slickest way to package this,
but it's a straightforward illustration of the is_pointer
feature.)

> Regards
> Heinz-Mario Frühbeis


Good luck.


K. Frank

Heinz-Mario Frühbeis

unread,
May 26, 2016, 4:06:56 AM5/26/16
to
Am 26.05.2016 um 03:33 schrieb Stefan Ram:
> "K. Frank" <kfran...@gmail.com> writes:
>> std::is_pointer<T>::value;
>
> Ew, »::value«, that is sooo C++11!
>
> (No, seriously, »::value« is ok. Since C++14, there also is
> an »operator()«.)
>

Hi!

Thank you both very<!> much! It is working perfectly!

But now I have a further question...

template < class t_MapMember >
class c_IDAMap{
typedef std::pair < std::string, t_MapMember > tPair;
typedef std::vector < tPair > tVec;
t_MapMember *nMember = NULL; // I'm using it currently [1]
// ...
}

template < typename t_ItemGet >
t_MapMember& operator [] (t_ItemGet vKey){
typename tVec::iterator itrTVec;
int nPos = -1;
nPos = GetPos(vKey);
if(nPos == -1){
return *nMember; // <-- [1]
} else{
itrTVec = vecMembers.begin();
advance(itrTVec, nPos);
}
return itrTVec->second;
}

[1]:
At this point there is no match found...
E.g.:
class A{
public:
std::string mString;
...
A(){mString = Hallo;}
}
c_IDAMap <A*> mMap;
Now adding e.g. "Hallo" and "Hi" (as Key!) ...
And than calling:
cout << mMap["Hallo"]; // Output is "Hallo"

But calling...
cout << mMap["Halo"];
raises an error, which I currently cannot handle really good and the
program crashes. The really problem is if the template is a pointer,
because I'm not able to return NULL.
Maybe because of 't_MapMember& operator [] (t_ItemGet vKey){' and the
'&' after 't_MapMember'.
It always returns a value other than NULL, so I cannot "ask" (if the
template contains pointer)...

if(mMap["Halo") == NULL) return; // E.g. ...

Do someone have a suggestion how I can return NULL in case of a mismatch?

Regards
Heinz-Mario Frühbeis

K. Frank

unread,
May 26, 2016, 12:35:26 PM5/26/16
to
Hi Heinz-Mario!

On Thursday, May 26, 2016 at 4:06:56 AM UTC-4, Heinz-Mario Frühbeis wrote:
> ...
> But now I have a further question...
> ...
> c_IDAMap <A*> mMap;
> Now adding e.g. "Hallo" and "Hi" (as Key!) ...
> And than calling:
> cout << mMap["Hallo"]; // Output is "Hallo"
>
> But calling...
> cout << mMap["Halo"];
> raises an error, which I currently cannot handle really good and the
> program crashes. The really problem is if the template is a pointer,
> because I'm not able to return NULL.
> Maybe because of 't_MapMember& operator [] (t_ItemGet vKey){' and the
> '&' after 't_MapMember'.
> It always returns a value other than NULL, so I cannot "ask" (if the
> template contains pointer)...
>
> if(mMap["Halo") == NULL) return; // E.g. ...
>
> Do someone have a suggestion how I can return NULL in case of a mismatch?

The general question you are asking is how to signal
that a key is not found when looking it up in a
collection, for example, in a key-value map.

Three approaches are common:

You can return a sentinel value -- a special value
not otherwise used that is deemed to mean "key not
found."

(In your specific case where you have a collection
of pointers, "c_IDAMap <A*> mMap;", if you know that
you will never store nullptr as a valid value in
your collection, then returning nullptr as the "key
not found" value could, indeed, work. If nullptr
could be a valid value, then this approach won't
work. Also, because you've made your collection
a class template whose stored type is not required
to be a pointer, you would need extra handling to
make your template code work sensibly for both pointer
and non-pointer types.)

You can return a default value. (See, for example,
how std::map::operator[] behaves when the key is not
found.)

You can throw an exception.

All of these work and can make sense depending on the
details of what you are trying to do. I would suggest
that you think about your use case, decide which of
these strategies makes the most sense for you, and then
drill down into the implementation details.
0 new messages