1

このようなクラスの構造があるとしましょう: 、、、およびクラスObjectの親クラスであるbase class 。、 などの関数をクラス内およびすべての子クラス内の仮想関数として使用する前に、これらの関数を個別に実装しました。BoolIntFloatBytesUnicodeBool cast_bool() constInt cast_int() constObject

より良い解決策は、template <typename TYPE> TYPE cast() const代わりに関数を実装することです。ただし、C++ では仮想テンプレート関数が禁止されているため、このタスクを完了する方法がわかりません。私が必要としているのは、 とその子を提供することtemplate <typename TYPE> TYPE cast() constですObject。ジェネリックObject::cast<TYPE>() constは単にスローしCastErrorます; Bool次に、 、 などのすべての型に対して。 、 などのInt関数を実装します。組み込みオブジェクトにキャストを追加することも計画していますが、今は 、 などをオーバーロードするだけです。実装がない場合、テンプレートはに切り替える必要があります。クラスからの一般的な形式で、エラーをスローするだけです。それを行う方法はありますか (おそらく、いくつかのパターンを使用する必要があります)? または、次のような関数を残す方が簡単ですか? 前もって感謝します!Bool::cast<Bool>() constInt::cast<Bool>() constoperator bool() constoperator signed short() constObjectInt cast_int() const

4

5 に答える 5

3

以下の例のように中間クラスを追加するdynamic_castか、テンプレート メソッドなしで使用します。

#include <iostream>
#include <string>
using namespace std;

template <class> class ObjectImpl;

class Object
{
public:
    virtual ~Object() {}

    template <class T>
    T cast() const
    {
        if (auto obj = dynamic_cast<const ObjectImpl<T>*>(this))
        {
            return obj->cast();
        }
        else
        {
            throw std::string("cast error");
        }
    }
};

template <class T>
class ObjectImpl : public Object
{
public:
    virtual T cast() const = 0;
};

class Bool : public ObjectImpl<bool>
{
public:
    bool cast() const override { return true; }
};
class Float : public ObjectImpl<float>
{
public:
    float cast() const  override { return 12.34f; }
};

int main()
{
    Object* obj = new Float;

    cout << obj->cast<float>() << endl;

    try
    {
        cout << obj->cast<bool>() << endl;
    }
    catch (std::string e)
    {
        cout << e << endl;
    }

    return 0;
}
于 2013-07-11T06:50:21.230 に答える
0

あなたがしていることはあまり良い考えのようには聞こえません.C ++はJavaでもC#でもありません...それでも、次のようにすることができます:

class Object
{
public:

     template<typename T>
     T& cast()
     {
          return cast_impl(std::declval<T>());
     }

private:
     virtual bool& cast_impl(bool&){ throw std::bad_cast(); }
     virtual int& cast_impl(int&){ throw std::bad_cast(); }
};

class Boolean : public Object
{
    bool value_;
public:

private:
     bool& cast_impl(bool) override
     { 
         return value_;
     }
};
于 2013-07-11T06:40:36.920 に答える
0

オブジェクトの型ラッパーを作成できます。

struct TypeWrapperBase
{
protected:
    static int m_counter;
};

int TypeWrapperBase::m_counter = 0;

template<typename T>
struct TypeWrapper:
    TypeWrapperBase
{
    static int m_type;
protected:
    static int AllocateType()
    {
        m_counter++;
        return m
    }
public:
    static int GetType()
    {
        return m_type;
    }   
};

template<typename T>
int TypeWrapper<T>::m_type = TypeWrapperBase::m_counter++;

void main()
{
    std::cout << TypeWrapper<int>::GetType() << std::endl;   // prints 0
    std::cout << TypeWrapper<float>::GetType() << std::endl;  // prints 1
    std::cout << TypeWrapper<bool>::GetType() << std::endl; // prints 2
}

このようにして、el1.GetType() と el2.GetType() を比較することで、任意のオブジェクトをシミュレートできます。等しい場合は、静的キャストを実行できます

于 2015-05-04T07:54:11.970 に答える
0

ランタイムキャストに問題がない場合の別の代替手段。

class Object
{
public:

     template<typename T>
     T& cast()
     {
          return *dynamic_cast<T*>(get());
     }

private:
     virtual void* get() = 0;
};

class Boolean : public Object
{
    bool value_;
public:

private:
    void* get() override
    {
        return &value_;
    }
}
于 2013-07-11T07:43:06.570 に答える