4

让我们考虑以下示例,说明隐式类型转换在哪里 起作用以及在哪里不起作用

#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++ 标准委员会认为这是一个坏主意?

4

1 回答 1

2

它不起作用,因为您在执行以下操作时从不要求编译器进行转换:

it->write();

我想它应该与 static_cast 一起使用:

static_cast<Thingy&>(*it).write();

但我几乎不确定你应该简单地使用:

it->get_a().write();

或者更好,正如其他人所说,在 Node.js 中声明一个 write 方法。

隐式转换可能是邪恶的。

因为您不能更改 f 函数,所以您应该只包装迭代器,以便它可以取消引用 Thingy 而不是节点,如果您可以使用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 上工作(但肯定也在旧版本上)。

您试图通过添加“隐式”间接来解决您的问题,但在这种情况下,它无法工作。您可以通过添加显式间接来解决它。

要回答您的问题,幕后没有哲学。它纯粹是机械的,C++ 使用在编译时解析的类型,所以所有东西在执行时间之前都有它的类型。您希望编译器如何猜测必须在 Node.js 上调用转换运算符?

于 2013-08-11T14:14:43.797 回答