0

C ++テンプレートクラスを使用してオブジェクトタイプを区別できますか?または私は何を使うべきですか?

例えば。私はクラスを持っています、そしてそれは例えばSynonymタイプであることができます。Statement, Procedure, etcこれらの同義語を受け入れ、そのタイプに応じて評価する関数があります。だから私は次のようなことができればいいと思っていました:

enum Types { Statement, Procedure, Variable, ... };

template <typename Types>
class Synonym { ... }

void evaluate(Synonym<Statement> s, Synonym<Variable> v) { do something }
              ^ so that I can do this ... instead of checking the type in function like: 

void evaluate(Synonym s, Synonym v) {
    assert(s.type == Statement);
    assert(v.type == Variable);

    // also would like to eliminate things like: (if possible)
    switch(s.type) {
        case XXX: doSomething ... 
        case YYY: doAnotherThing ...
    }
}
4

2 に答える 2

0

バリアントとビジター パターンを使用するのが適していると思います。ここで Boost.Variant を見てください: http://www.boost.org/doc/libs/1_51_0/doc/html/variant.html、最後の例 (これも下にありますが、展開されています) は、ビジターの実装を示しています。他のバリアントとビジターの実装もあります。std::any と loki もオプションです。私は個人的にロキが好きですが、それはおそらく私がアレクサンドレスクの大ファンだからです.

#include "boost/variant.hpp"
#include <iostream>

class ToLengthVisitor : public boost::static_visitor<int>
{
public:
    int operator()(int i) const
    {
        return i;
    }

    int operator()(const std::string & str) const
    {
        return str.length();
    }

    int operator()(const char * str) const
    {
        const char * temp = str;
        while(*temp != '\0') temp++;
        return temp-str;
    }
};

int main()
{
    typedef boost::variant< int, std::string, const char * > MyVariant;
    MyVariant u(std::string("hello world"));
    std::cout << u; // output: hello world

    MyVariant cu(boost::get<std::string>(u).c_str());

    int result = boost::apply_visitor( ToLengthVisitor(), u );
    std::cout << result; // output: 11 (i.e., length of "hello world")
    result = boost::apply_visitor( ToLengthVisitor(), cu );
    std::cout << result; // output: 11 (i.e., length of "hello world")
}
于 2013-02-21T14:37:19.177 に答える
0

関数テンプレートを作成し、そのテンプレートに特化することができます

template<typename Type>
void evaluate (Type t) {}

template<>
void evaluate<Statement>( Statement s)
{}

このように、 a を渡すと、Statementそのオーバーロードが選択され、タイプに応じてさまざまな動作を実行できます。

于 2013-02-21T14:15:16.627 に答える