5

注: この質問で提供されている例は、製品コードではなく、まったく意味がありません。私の問題を説明するためにそこにあるだけです。

の可能性をテストしていましたdecltype。特に、関数のパラメーターの型を推測するために使用されている場合は、問題が発生しました。

次のような構造の 2 つのクラスがあるとします。

struct ClassInt
{
    // Note: no default ctor
    ClassInt(int value)
        :   m_Value(value)
    {}

    int  m_Value;
};

struct ClassDouble
{
    // Note: no default ctor
    ClassDouble(double value)
        :   m_Value(value)
    {}

    double  m_Value;
};

m_Valueここで、(何らかの方法で) 型パラメーター (上記のいずれか) のインスタンスを文字列で取得し、指定された値をそのメンバーに割り当てる関数を作成しました。

template< typename Ty >
Ty* get_fake_ptr() { return nullptr; }


// Retrieve pointer to Ty object by name and assign its value member.
// The problem is that we don't actually have an instance of Ty at the point
// where we want to define the type of the parameter "value".
template< typename Ty >
void assign(std::string name, decltype(get_fake_ptr<Ty>()->m_Value) value)
{
    // Somehow get pointer to a Ty object by name
    Ty* obj = ????;

    // Assign
    obj->m_Value = value;
}

現在、value使用されるクラスは member の型が異なるため、パラメーターの型は型パラメーターに依存していますm_Value。ご覧のとおり、を使用して解決しましたdecltype。さて、通常、次decltypeのようにパラメーターで使用します。

template<typename Ty>
void assign(Ty& obj, decltype(obj.m_Value) value);

しかし、実際のインスタンスは関数本体で取得され、関数の引数が宣言された時点では使用できないため、ここでは明らかに不可能です。

get_fake_ptr一致する型の を返すテンプレート関数を使用して一緒にハックしたnullptrので、コンパイラがメンバー型を決定するために使用できる「疑似インスタンス」があります。そしてそれは動作します:

働く

さて、私が言ったように、これは私には本当にハックに思えます。そう:

この問題を解決するより良い方法はありますか?

ありがとうございました!

4

3 に答える 3

3

このアプローチには何の問題もありません。

テンプレートのメタプログラミングに関して言えば、これらの種類の「ハック」は当然のことです。

ただし、少し異なるデザイン パターンを提案することはできます。このようなもの:

struct ClassInt
{
    // Note: no default ctor
    ClassInt(int value)
        :   m_Value(value)
    {}

    typedef int m_value_t;

    m_value_t  m_Value;
};

struct ClassDouble
{
    // Note: no default ctor
    ClassDouble(double value)
        :   m_Value(value)
    {}

    typedef double m_value_t;

    m_value_t  m_Value;
};

// ...
template< typename Ty >
void assign(std::string name, typename Ty::value_t value)
{
    // Somehow get pointer to a Ty object by name
    Ty* obj = ????;

    // Assign
    obj->m_Value = value;
}
于 2015-09-21T02:58:35.860 に答える
3

関数を使用する代わりに、のメンバーdecltype(std::declval<T>().m_Value)の型を推測するために使用できます。彼らは最終的に同様の目標を達成します。Tm_Valueget_fake_ptr()

ところで、get_fake_ptr()関数を定義する必要はありません。そのままにしておくだけでtemplate <typename T> T* get_fake_ptr();、内部で引き続き使用できますdecltype

于 2015-09-21T03:31:28.030 に答える