让我们考虑以下示例隐式类型转换 的工作原理以及不的位置:
#include <iostream>
#include <vector>
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();
}
int main()
{
std::vector<Node> vector(10);
f(vector.begin(), vector.end()); // Doesn't compile
f(vector[3]); // compiles
vector[3].write(); // Doesn't compile
return 0;
}
为什么会这样?
void Node::write();
不应与以下方面有所不同:
void write(Node* this);
有没有办法让我的示例代码编译并运行?
编辑:
我理解为什么它不起作用的机制,我想理解这个哲学。为什么C ++标准委员会认为这是一个坏主意?
答案 0 :(得分:2)
它没有用,因为你在做的时候从不要求编译器进行转换:
it->write();
我想它应该适用于static_cast:
static_cast<Thingy&>(*it).write();
但我几乎不确定你应该只使用:
it->get_a().write();
或者更好,正如其他人所说,在Node中声明一个方法写入。
隐含的转换可能是邪恶的。
因为你不能改变f函数,你应该只是包装迭代器,这样它可以取消引用Thingy而不是Node,如果你可以使用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 n.a; }
};
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;
}
使用g ++ 4.8.1(但肯定也是旧版本)。
您尝试通过添加&#34;隐式&#34;来解决您的问题。间接,但在这种情况下,它无法工作。您可以通过添加显式间接来解决它。
要回答你的问题,现场背后没有哲学。它纯粹是机械的,C ++使用的类型在编译时被解析,因此在执行时间之前一切都有它的类型。您希望编译器如何猜测必须在Node上调用转换运算符。