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 でメソッド書き込みを宣言します。

暗黙の変換は悪になる可能性があります。

f 関数を変更することはできないため、イテレータをラップして、Boostを使用できる場合は Node ではなく Thingy を逆参照できるようにする必要があります。

#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 に答える