0

ネイティブタイプのような構造体間の明示的な変換を強制したい:

int i1;
i1 = some_float; // this generates a warning
i1 = int(some_float): // this is OK
int i3 = some_float; // this generates a warning

代入演算子とコピーコンストラクターを使用して同じことを行うことを考えましたが、動作が異なります。

Struct s1;
s1 = other_struct; // this calls the assignment operator which generates my warning
s1 = Struct(other_struct) // this calls the copy constructor to generate a new Struct and then passes that new instance to s1's assignment operator
Struct s3 = other_struct; // this calls the COPY CONSTRUCTOR and succeeds with no warning

Struct s3 = other_struct;デフォルトのコンストラクターを使用して3番目のケースのコンストラクトs3を取得し、代入演算子を呼び出すためのトリックはありますか?

これはすべて、必要に応じてコンパイルおよび実行されます。C ++のデフォルトの動作は、新しいインスタンスを作成してコピーコンストラクターを一度に呼び出すときに、代入演算子の代わりにコピーコンストラクターを呼び出すことですつまり、;ではありませんMyStruct s = other_struct;。それを回避するためのトリックがあるかどうか疑問に思っています。 。MyStruct s(other_struct)MyStruct s; s = other_struct;

編集:「明示的な」キーワードは私が必要としていたものです!

class foo {
    foo(const foo& f) { ... }
    explicit foo(const bar& b) { ... }
    foo& operator =(const foo& f) { ... }
};

foo f;
bar b;
foo f2 = f; // this works
foo f3 = b; // this doesn't, thanks to the explicit keyword!
foo f4 = foo(b); // this works - you're forced to do an "explicit conversion"
4

4 に答える 4

4

免責事項:これは質問に答えないため、これについて反対票を投じる準備ができています。しかし、これはOPに役立つ可能性があります。

コピーコンストラクターをデフォルトの構築+代入と考えるのは非常に悪い考えだと思います。それは逆です:

struct some_struct
{
    some_struct();  // If you want a default constructor, fine
    some_struct(some_struct const&); // Implement it in the most natural way
    some_struct(foo const&);         // Implement it in the most natural way

    void swap(some_struct&) throw(); // Implement it in the most efficient way

    // Google "copy and swap idiom" for this one
    some_struct& operator=(some_struct x) { x.swap(*this); return *this; }

    // Same idea
    some_struct& operator=(foo const& x)
    {
        some_struct tmp(x);
        tmp.swap(*this);
        return *this;
    }
};

そのように物事を実装することは絶対確実であり、C++ での変換セマンティクスに関して得られる最高のものであるため、ここに進む方法です。

于 2010-09-17T17:27:47.660 に答える
3

other_struct の型キャスト演算子をオーバーロードし、それに応じて元の構造を編集すると、これを回避できます。とはいえ、これは非常に面倒であり、一般的にそうする正当な理由はありません。


#include <iostream>

using namespace std;

struct bar;

struct foo {
    explicit foo() {
        cout << "In foo default constructor." << endl;
    }

    explicit foo(bar const &) {
        cout << "In foo 'bar' contructor." << endl;
    }

    foo(foo const &) {
        cout << "In foo constructor." << endl;
    }

    foo const & operator=(bar const &) {
        cout << "In foo = operator." << endl;
        return *this;
    }
};

struct bar {
    operator foo() {
        cout << "In bar cast overload." << endl;
        foo x;
        x = *this;
        return x;
    }
};

int main() {
    bar b;
    foo f = b;
    return 0;
}

出力:

In bar cast overload.
In foo default constructor.
In foo = operator.
In foo constructor.
In foo constructor.
于 2010-09-17T17:19:34.613 に答える
2

要するに、いいえ。

長いバージョンは...実際にはそれについてです。それはそれがどのように機能するかではありません。ただし、キャラクターの要件を満たすために何かを考え出す必要がありました。

于 2010-09-17T16:52:57.510 に答える
0

私はそうは思わない。あなたが書くとき

Struct s3 = other_struct;

割り当てのように見えますが、実際にはコンストラクターを呼び出すのは宣言型の構文です。

于 2010-09-17T16:53:42.320 に答える