让我们考虑以下示例,这些示例说明了隐式类型转换 在哪些地方起作用以及在哪些地方不起作用:
#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 ++标准委员会认为这是个坏主意?
这是行不通的,因为您在执行操作时从不要求编译器进行转换:
it->write();
我猜它应该与static_cast一起工作:
static_cast<Thingy&>(*it).write();
但我几乎不确定您应该简单地使用:
it->get_a().write();
就像其他人所说的那样,更好的方法是在Node中声明一个写方法。
隐式转换可能是邪恶的。
因为您不能更改f函数,所以应该包装迭代器,以便可以使用Boost来取消引用Thingy而不是Node的引用:
#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上工作(但肯定也在旧版本上工作)。
您试图通过添加“隐式”间接解决问题,但是在这种情况下,它不起作用。您可以通过添加显式间接解决它。
要回答您的问题,幕后没有哲理。这纯粹是一种机制,C ++使用在编译时解析的类型,因此一切在执行之前就具有其类型。您希望编译器如何猜测必须在Node上调用转换运算符。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句