5

これができないことを強く示唆するスレッドをいくつか見つけましたが、まったく同じ演算子と条件の組み合わせを使用するスレッドはありません。そのため、より具体的にお尋ねしたいと思います。うまくいけば、それが誰かにとって迅速かつ簡単な答えになることを意味します...何らかの形で!

ストレージのより大きなブロック内の値を管理するために作成されたプロキシ クラスの例を考えてみましょう。

class SomeProxyThing {
    std::uint32_t storage;

public:
    operator std::uint16_t() const
    {
        return storage & 0x0000FFFF;
    }

    SomeProxyThing &operator=(std::uint16_t const value)
    {
        storage &= 0xFFFF0000;
        storage |= value;
    }
};

すべて割り当てがユーザー定義operatorの s を介して機能するようにします。ユーザーは、この場合、「公開された」タイプのみを渡したり取り出したりできる必要がありますstd::uint16_t。さまざまなプロキシ クラス タイプを使用している可能性があり、これをそれらすべてに適用したいと考えています。理想的には、どのような型の組み合わせでも、型を入力するだけで、後someProxy = anotherProxyはコンパイラーに任せることができます。

しかし、代入の左側と右側が同じ型または継承に関連する型を持つ場合、デフォルトのコピー代入演算子 (もちろん) はこの目標と競合します。必要に応じて「公開された」値だけをコピーするのではなく、全体をコピーするstorageため、残りの半分を上書きします。uint32_tそして当然のことです!ほとんどの場合。しかし、LHS と RHS の型が同じであっても、「変換によって割り当てる」方法が欲しいです。これを回避するために、次のことができます。

  • operatorユーザー定義の sを使用して「プロキシ」コピーを実行するようにコピー代入演算子を再定義ます。の- 私が保持する必要があるものとにかくまだsですが、定義された動作が必要です。structmemcpy()g++
  • または= deleteコピー代入演算子(TC 型に対して実行できるようになりました)。しかし、割り当てはまだそれを使用しようとし、コンパイル エラーをスローしますdelete。これは、「オーバーロードの解決から私を除外する」のではなく、「選択されたオーバーロードの場合にエラーで中止する」ことを意味するためです。これを回避するには、変換演算子を使用してその結果から割り当てるようにコンパイラに明示的に指示する必要があります。
SomeProxyThing a, b;
a = 42;
b = static_cast<std::uint16_t>(a);
// a.k.a.
b.operator=( a.operator std::uint16_t() );

コンパイラに「優先オーバーロードによって生成されたエラーを無視し、次善のものを選択する」ように指示する方法はないようです。ある?より一般的には、そのような状況で、コンパイラに特定の sを自動的に使用/優先させるoperator方法/ハック/恐ろしいクラッジはありますか?

つまり、理想的には、

SomeProxyThing a, b;
a = 42;
b = a;

それb = a;は本当にこれを行うでしょう:

b = static_cast<std::uint16_t>(a);
// a.k.a.
b.operator=( a.operator std::uint16_t() );

これを手動で入力したり、 を使用しstatic_castたり、名前付きの get/set メソッドを実装したりする必要はありません。理想的には、そのようなプロキシへの読み取り/書き込みは、すべて=.

私はそれが不可能だと強く思っています...しかし、確認はいいでしょう!

4

2 に答える 2

1

あなたはこれを行うことができます:

#include <stdint.h>
#include <iostream>
#include <type_traits>

using namespace std;

class Proxy_state
{
protected:
    uint32_t storage;
public:
    // Access to the bytes
};

static_assert( is_trivially_copyable<Proxy_state>::value, "!" );

class Some_proxy_thing
    : public Proxy_state
{
private:

public:
    operator std::uint16_t() const
    {
        return storage & 0x0000FFFF;
    }

    auto operator=( uint16_t const value )
        -> Some_proxy_thing&
    {
        clog << "=(uint16_t)" << endl;
        storage &= 0xFFFF0000;
        storage |= value;
        return *this;
    }

    auto operator=( Some_proxy_thing const& value )
        -> Some_proxy_thing&
    { return operator=( static_cast<uint16_t>( value ) ); }
};

static_assert( not is_trivially_copyable<Some_proxy_thing>::value, "!" );

auto main()
    -> int
{
    Some_proxy_thing    a{};
    Some_proxy_thing    b{};
    const Some_proxy_thing c = b;

    a = c;

    a = 123;
    a = b;
}

ここでは、3 つの割り当てすべてが (標準エラー ストリームに) 出力されます=(uint16t)

于 2016-07-12T19:22:54.577 に答える