Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Error with generics, pointers and const

Status
Not open for further replies.

globos

Programmer
Nov 8, 2000
260
FR
Hi,

I have a problem with the compilation of some code. It appears when mixing generics with pointers and const.
Here is a dummy sample :

Code:
class Object//Our dummy data class
{};

template<class G>//A generic class defining a request
class A
{
public:
  bool has (const G& v) const
  { return true; }

};

class B//Uses A<> with pointers.
{
public:
  bool found (const A<Object*>& a, const Object& v) const
  { return a.has (&v); }
};


int main ()//some test
{
  A<Object*> a;
  Object obj;

  B b;
  b.found (a, obj);

  return 0;
}

The compilation error is :
main-test.cpp(23) : error C2664: 'has' : cannot convert parameter 1 from 'const class Object *' to 'class Object *const & '
Reason: cannot convert from 'const class Object *' to 'class Object *const '
Conversion loses qualifiers

I can't understand why this error occurs, looking at the source code, it seems valid.
What must I do to avoid the problem?

--
Globos
 
It's a very interesting case.
Code:
  bool found (const A<Object*>& a, const Object& v) const
  { return a.has (&v); }
So &v expression yields a pointer to a constant object.
Its type is (const Object*).
We have in template:
Code:
  bool has (const G& v) const
We can't modify v (so it's type is Object*const) in has().
In class B we have (const Object*) pointer in a.has(&v)
and trying to pass it to a function which
accepts Object*const argument.
No standard conversion between const* and *const.
Try
Code:
  bool found (const A<Object*>& a, const Object& v) const
  { return a.has (const_cast<Object*const>(&v)); }
 
ArkM,

I have tried with the const casting, it compiles. But it will be really painful to use. Apparently there does not seem to be other solutions. I have also tried to play with the const, but the current signatures reflect right const semantics, it should stay like this.
I still can't understand the compiler error in :
Code:
bool has (const G& v) const
ArkM said:
We can't modify v (so it's type is Object*const) in has().
The actual type of v should be `const Object*&' (G = Object*) and not `Object*const'. Why is it not so?

--
Globos
 
globos said:
The actual type of v should be `const Object*&' (G = Object*) and not `Object*const'. Why is it not so?

The type of [tt]G[/tt] is "pointer to Object."

So the type of [tt]const G[/tt] is "const pointer to Object," not "pointer to const Object."


Try something like this:
Code:
template<typename T>
struct PtrConstify
{
  typedef const T Type;
};

template<typename T>
struct PtrConstify<T*>
{
  typedef const T * Type;
};

...

bool has (PtrConstify<G>::Type& v) const


If you need to do stuff like that frequently, check out the TypeTraits facility in the Loki library available at
 
Actually,
Code:
bool has (PtrConstify<G>::Type& v) const
probably won't compile...

Better try
Code:
bool has ([highlight]typename[/highlight] PtrConstify<G>::Type& v) const
 
A constant pointer to X has type X*const (see C++ Standard 8.3.1(2)).
A type const X* is a pointer to a constant X.
const X& is a reference to a const X. It's a type of v parameter in template member function.
Now let's substitute...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top