C++ templates, problem with object allocated both "static" and "dynamic"
What is wrong in this code?
template <typename T>
class Sample
{
public:
T first;
T second;
typedef T Type;
};
and
template <typename Item>
class Process
{
public:
void process (Item *item)
{
typename Item::Type var = item->first + item->second;
//Some code...
}
};
The method "process" should be able to work with an object allocated both "static" and "dynamic"...The firs开发者_如何学Ct option works
int main(int argc, _TCHAR* argv[])
{
Sample <double> s;
Process <Sample <double> > a;
a.process(&s);
return 0;
}
but the second not
int main(int argc, _TCHAR* argv[])
{
Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a;
a.process(s); //Error C2664: 'Process<Item>::process' : cannot convert parameter 1 from 'Sample<T> *' to 'Sample<T> *'
return 0;
}
How to design a class and method "process" so as to be able to work with an object allocated both "static" and "dynamic" ? Thanks for your help...
Process <Item>::process()
expects a Item*
, so Process <Sample <double> *>::process()
expects a Sample <double>**
.
The solution is much easier, however:
Sample <double> *s = new Sample <double>();
Process <Sample <double> > a;
a.process(s);
For Process
, it doesn't matter at all how the object was allocated, all it gets is a pointer to it and works with it (assuming it won't maintain ownership or attempt to delete the object).
Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<<----------- here you go wrong!
a.process(s);
The argument to Process
should still be Sample<double>
, not Sample<double>*
, since the latter makes Item*
=> Sample<double>**
, which you're not passing when calling process
member function.
So the correct code should be this:
Process <Sample<double> > a; //<<----------- now it's correct!
a.process(s);
This should work now!
Or do this:
Sample <double> *s = new Sample <double>();
Process <Sample <double> *> a; //<------ your version!
a.process( &s ); //<------ note I'm passing pointer to pointer!
// ^^ note the ampersand (&)
The issue isn't the fact that the object was allocated a certain way. It's not possible to tell whether if an object was allocated on the stack or the free store given its pointer alone, at least though any portable, standard means. Accessing members of an object through a pointer happens the exact same way for both "stack" objects and "free store" objects.
The actual issue is that you're passing the wrong type to the Process<>
variable definition in the second snippet:
Process <Sample <double> *> a;
Take a look at the definition of Process<>
:
template <typename Item>
class Process
{
public:
void process (Item *item)
{ /* ... */ }
};
When Item
is of type Sample <double> *
, then the function signature for process()
becomes:
void process (Sample <double>** item)
{ /* ... */ }
Which is not what you want, apparently.
To fix this, change
Process <Sample <double> *> a;
to
Process <Sample <double> > a;
With the latter, the function signature for process()
becomes void process (Sample <double>* item)
, which should allow both of your code snippets to compile.
Process <Sample <double> *> a;
a.process(s);
The Process.process
signature for the above code would be void process(Sample <double> **)
since Item
is Sample <double> *
- You want it to be void process(Sample <double> *)
Change this:
Process <Sample <double> *> a;
To:
Process <Sample <double> > a;
If you look at the full error message, likely the compiler is telling you about the two different T
's used when trying to match one Sample<T>
with another Sample<T>
精彩评论