void mbsNormalNode::Setup(vectorWhat is the correct way to "cast" this vector. Will I have to use a normal loop to copy from my existing vector to the vector of base objects. If so, doesn''t this defeat the purpose of generic programming?& vnNewNodes, vector & iNewWeights, int& iNewThreshold){ vector vnBaseNodes; copy(vnNewNodes.begin(), vnNewNodes.end(), back_inserter(vnBaseNodes.begin())); Setup(vnBaseNodes, iNewWeights, iNewThreshold); }
🔒 Locked
Casting and iterators.
Advertisement
Original Post
I''ve written the following member with the intention of ''casting'' a vector of type mbsTileNode* to a vector of type mbsNode* and then calling the ''true'' setup function. However, my compiler vomits, and I mean vomits, at this. I was surprised by this as mbsNode is the base class of mbsTileNode so all I am rquesting the function to do is straightforward upcast.
I tried
vector vnBaseNodes(vnNewNodes.begin(), vnNewNodes.end());
and the compiler, gcc, came back with:
/usr/include/c++/3.2/bits/stl_algobase.h:241: cannot convert
Also, I'm a bit wary of using the template approach as this seems to underming C++ type safety.
[edited by - tifkagh on February 23, 2003 4:28:26 PM]
vector
and the compiler, gcc, came back with:
/usr/include/c++/3.2/bits/stl_algobase.h:241: cannot convert
mbsTileNode*' to mbsNode*' in assignmentAlso, I'm a bit wary of using the template approach as this seems to underming C++ type safety.
[edited by - tifkagh on February 23, 2003 4:28:26 PM]
To convert from one pointer type to another it needs to be able to see that they are related by inheritance. Include the correct headers.
sorry AP, I don''t know who you are or the quality of what you normally say, but your terminology is wrong, back to front and made up.
downcast - cast from a base class to a derived class
upgrade - improve with new technology
downcast - cast from a base class to a derived class
upgrade - improve with new technology
You can try a void *
mbsTileNode *tmp1;
mbsNode *tmp2;
tmp2 = (void*)tmp1;
This way, it CAN convert tmp1 to a void*, and tmp2 can be assigned a void*... or at least in theory
. I''ve done what you''re saying, and it works fine for my code, in MSVC++ 6.0 though. It does however, give me a warning that there is no conversion for going from the base class to the new class, but it''s just a warning, and still works properly. I don''t see why you wouldn''t be able to directly cast the way you''re trying to though, isn''t that the point of inheriting, so you can treat all objects similarly, without needing to know the specific type?
mbsTileNode *tmp1;
mbsNode *tmp2;
tmp2 = (void*)tmp1;
This way, it CAN convert tmp1 to a void*, and tmp2 can be assigned a void*... or at least in theory
quote:
Original post by tifkagh
What is the correct way to "cast" this vector. Will I have to use a normal loop to copy from my existing vector to the vector of base objects. If so, doesn't this defeat the purpose of generic programming?
As you may have expected, the correct thing to do is not to cast the vector, and generally you should never cast an iterator (the only exception is casting to or from const to non-const iterators).
The code you posted is not generic. Using a for-loop does not defeat generic programming (it does grind against functional programming).
Rewrite the orginal Setup function (that has the loop in it), to take iterators as template parameters. This will make it a generic function.
template<typename NodeIt, typename WeightIt>
int Setup(NodeIt begin, NodeIt end, WeightIt weight, int threshold)
{
for(; begin!=end; ++begin, ++weight)
{
//This will access the node
(*begin)-> //use *weight, do something with threshold
}
return threshold;
}
Then you'd use it like so:
assert(newnodes.size() == weights.size());
new_threshold = Setup(newnodes.begin(), newnodes.end(), weights.begin(), threshold);
If threshold is a result, return it. If it's an input parameter, pass it by value.
[edited by - Magmai Kai Holmlor on February 24, 2003 12:39:37 PM]
quote:That''s not true. If you pass a container that has nodes of incompatible type, the compiler will complain. What the templates enable is polymorphism in a broader sense.
Original post by tifkagh
Also, I''m a bit wary of using the template approach as this seems to underming C++ type safety.
You can also try what Magmai Kai Holmlor said, but I don''t really know if there are any benefits of passing iterator instead of container here. Just another place where you''ll end up always writing "x.begin(), x.end()" IMO. Surely it''s more generic once again since you can pass any range or some stranger iterators (like reverse_iterator), but I doubt that''d ever be useful.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement