This does not work, because you never ask the compiler about conversion when you do:
it->write();
I assume it should work with static_cast:
static_cast<Thingy&>(*it).write();
But I'm barely sure you should just use:
it->get_a().write();
Or better, as others have said, to declare a write method in Node.
Implicit conversions can be evil.
Since you cannot change the function f, you just have to wrap the iterator so that it can cast Thingy instead of Node if you can use Boost :
#include <iostream> #include <vector> #include <boost/iterator/transform_iterator.hpp> struct Thingy { void write() { std::cout << "x" << std::endl; } }; struct Node { Thingy a; int data; operator Thingy&(){return a;} }; void f(Thingy thingy) { thingy.write(); } template <typename TIterator> void f (TIterator begin, TIterator end) { for (TIterator it = begin; it != end; ++it) it->write(); } struct Node2Thingy { typedef Thingy& result_type; Thingy& operator()(Node& n) const { return na; } }; int main() { std::vector<Node> vector(10); f(boost::make_transform_iterator(vector.begin(), Node2Thingy()), boost::make_transform_iterator(vector.end(), Node2Thingy())); f(vector[3]); // compiles return 0; }
Work on g ++ 4.8.1 (but probably also in the old version).
You tried to solve your problem by adding "indirect" indirection, but in this case it will not work. You can resolve this by adding an explicit indirect call.
There is no philosophy behind the scene to answer your question. These are purely mechanical types of C ++ usage that are allowed at compile time, so they all have their type until runtime. How do you want the compiler to suggest that the conversion operator should be called on Node.
source share