4

C++ で制約を実装する方法を示す例 (またはこれを簡単に実行できるブースト ライブラリ) を探していましたが、あまり運がありませんでした。私が思いついた最高のものは次のとおりです。

#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>

template<typename T>
class constrained
{
    public:
        constrained(boost::function<bool (T)> constraint, T defaultValue, T value = defaultValue)
        {
            ASSERT(constraint(defaultValue));
            ASSERT(constraint(value));

            this->value = value;
            this->defaultValue = defaultValue;          
            this->constraint = constraint;                      
        }

        void operator=(const T &assignedValue)
        {
            if(constraint(assignedValue))
                value = assignedValue;      
        }   

    private:
        T value;
        T defaultValue;
        boost::function<bool (T)> constraint;
};

int main(int argc, char* argv[])
{
    constrained<int> foo(boost::lambda::_1 > 0 && boost::lambda::_1 < 100, 5, 10);

    foo = 20; // works
    foo = -20; // fails

    return 0;
}

もちろん、制約クラスに必要な機能が他にもあるでしょう。これは出発点としてのアイデアにすぎません。

とにかく、私が目にする問題は、T が実際に T のように動作するようにするには、T が定義するすべての演算子をオーバーロードする必要があり、それらが何であるかを知る方法がないことです。さて、実際にはそれほど多くの異なるタイプの制約は必要ないので、テンプレートを省略してハード コードするだけで済みます。それでも、一般的な(または少なくともより簡潔でエレガントな)解決策があるかどうか、または私のアプローチに深刻な問題があるかどうか疑問に思っています。

4

6 に答える 6

4

小さな例としてはよさそうです。ただし、必ずすべての演算子を実装し、何らかの形で間違った値を処理してください。

foo = 100; // works
++foo; // should throw an exception or perform an assert

ブースト演算子を使用して、演算子のオーバーロードを支援します。

そしておそらく、テンプレート パラメーターとして、例外またはアサーションのいずれかのオプションがあるとよいでしょう。

私はそのようなクラスを使用します。ベクトル範囲を自動チェックしてアサーションを行うインデックス パラメータを使用することを常にお勧めします。

void foo( VectorIndex i );
于 2009-04-15T11:48:37.470 に答える
2

私は、ブーストオペレーターが役立つというMykolaGolubyevに同意します。

使用しているすべてのタイプに必要なすべての演算子を定義する必要があります。

使用しているタイプのいずれかが演算子をサポートしていない場合(たとえば、operator ++())、このメソッドを呼び出すコードはコンパイルされませんが、他のすべての使用法はコンパイルされます。

タイプごとに異なる実装を使用する場合は、テンプレートの特殊化を使用してください。

于 2009-04-15T12:00:51.603 に答える
1

混乱するかもしれませんが、特定の制約に違反してはならないパラメーターに直面している場合は、コンストラクターと割り当て演算子で制約をチェックして、それらのクラスを作成するのが最も簡単ではないでしょうか。

于 2009-04-15T11:03:19.933 に答える
0

Boostは実際にそのようなライブラリを議論していました(私はそれがどうなったのかわかりません)。また、このようなタイプの独自のバージョンを作成しましたが、動作は少し異なります(柔軟性は劣りますが、単純です)。私はここで確かにいくらか偏った比較をブログに書きました:制約された値のタイプと制限された値のタイプ

編集:どうやらエリックは、ブーストの実装に何が起こったのかをよく知っています。

于 2009-04-15T13:07:26.670 に答える