2

C++ のすべての単純型に機能を追加しようとしています。

カプセル化する型をテンプレート パラメーターとして受け取り、すべての演算子を定義して、カプセル化されたクラスがカプセル化された単純な型とまったく同じように機能する、単一のテンプレート クラスを作成したいと考えています。

このようなもの:

template <typename _SimpleType_>
class Attribute
{
public:
    Attribute(_SimpleType_ value){ m_value = value; }
    ~Attribute(){}

    // Cast
    operator _SimpleType_() { return(m_value); }

    // Comparisons
    bool operator==(const a& other) const { return a == m_value; }
    etc...

private:
   _SimpleType_ m_value;
}

// Use like:
Attribute<int> i = 20;

while(i)
{
   if((i & 0xF) == 0)
   {
      i >>= 2;
   }

   i--;
}  etc...

問題は、対処しなければならない微妙なニュアンスがたくさんあり、特殊なテンプレート オペレーターが書かれていることです。代わりにそれを使用できるように、これが既に行われている場所はありますか?

ブーストは大きすぎて複雑すぎてプロジェクトに入れることができませんが、このようなクラスがそこにある場合はポインタを調べることができます-ある場合、その名前は何ですか?

4

6 に答える 6

4

退屈な場合でも、それは非常に簡単です-標準型でサポートされているすべての演算子を実装する必要があり、キャスト演算子では不十分です。

私は尋ねなければなりませんが、一体なぜあなたはこれをやろうとしているのでしょうか?

于 2009-02-12T00:12:49.820 に答える
3

以下は、T& への自動型キャストを行う例です (GNU C++ 4.3.2 でテスト済み)。

#include <iostream>

using namespace std;

template <typename T>
class Attribute {
public:
    Attribute(const T &value) { v = value; }
    operator T & () { return v; }
private:
    T v;
};

int main(int argc, char **argv)
{
    Attribute<int> i(0);
    i = 3;
    i++;
    i += 4;
    i = i + 5;
    i <<= 3;
    cout << "i is now " << i << endl;
}

C++ コンパイラは、強制演算子 'operator T & ()' を使用して、'Attribute' への参照を 'int' への参照に自動的にキャストします。したがって、Attribute クラスが「++」演算子などを提供しない場合、オブジェクトは int & に型キャストされ、そこから演算子が検索されます。お気軽に実験してください。

于 2009-02-12T00:44:01.993 に答える
2

に変換するだけで、不変演算子の実装を無料で_Simple_type_取得できます (また、 に変換することで代入とインクリメント/デクリメントを取得できます_Simple_type_&)。別の質問は、オーバーロード中に問題を引き起こすとTへの変換を作成するため、これが本当に良いアイデアであるかどうかですが、コンストラクターを明示的にすることで修正できます。Attribute<T>Attribute<T>TAttribute<T>

これにより、割り当てとインクリメント/デクリメントが残ります-それらを実装するだけです。

別の可能性はboost::operators、代数規則に基づいて演算子のオーバーロードの作成を容易にするヘッダーのみのライブラリを使用することです。例えば。あなたが作成operator+=し、それはあなたを提供しますoperator+operator<andを作成するとoperator==、他のリレーショナルなどが提供されます。

于 2009-02-12T00:27:03.750 に答える
1

あなたの質問とは関係ありませんが、次のような名前_SimpleType_(つまり、アンダースコアと大文字で始まる名前) は、C++ コンパイラと標準ライブラリの実装者が使用するために予約されていることに注意してください。使用は許可されていません。それらを独自のコードで。

于 2009-02-12T00:44:01.667 に答える
0

私はこの形式の単純なタイプのカプセル化が好きです(原作者-Sektor van Skijlen):

template<typename T>
class explicit_t
{
private:
    T value;

    template<typename V> explicit_t(V t);
public:
    operator T&() {return value;}
    explicit_t(const T& c) : value(c) {}    
}; 

そして短い例:

void fun(explicit_t<int> foo) {}

int main()
{
        // fun('a');
        // fun(3u);
        // fun(3.0);
        fun(4);
}

だから私は何を得るのですか?これ以上の不要な変換はありません。

また、もっと凝ったもの、 typegenも見てみたいと思うかもしれません。

于 2009-03-11T13:02:54.663 に答える
0

boost::refあなたが探しているものかどうかはわかりません。

とにかく、手で書き出すのが最善の方法ですが、ポインターと参照のセマンティクスをサポートするつもりなら、これは問題になり始めます。

また、おそらく行う必要があるのは、それを名前空間に配置し、無料の関数演算子のオーバーロードを実装し、それを取得するために ADL に依存することです。ただし、実装する演算子が増えるにつれて、これは少し扱いに​​くくなります。

于 2009-02-12T00:23:30.997 に答える