1

前回の質問で、テンプレートの専門化を機能させる上で大きな助けになりました。今、私は少し拡張が必要です。これらのステートメントには 2 つの特殊化が必要です。

int main()
{
    // First specialization
    holder_ext<person> h1;
    holder_ext<person, &person::age> h2;
    holder_ext<int> h3;

    // Second specialization
    holder_ext<person, &person::age, &person::name> h4;
}

私のクラスの人は次のようになります。

class person
{
private:
    std::string name_;
    int age_;
public:
    person(const std::string &name)
        : name_(name), age_(56)
    {}
    void age(int a) { age_ = i; }
    void name(const std::string &n) { name_ = n; }
};

特別なことは、2 つのメンバー関数のパラメーターの型が異なることです。したがって、両方に同じ可変個引数テンプレート メンバー関数を使用することはできません。2 つの異なる可変個引数テンプレートで試しました。しかし、それはうまくいきません。また、メンバー関数のデフォルト値は機能しません。

誰かが私に良いヒントを持っていますか?

これは、1 つのメンバー関数を使用したソリューションです ( Pubbyのおかげです)。

template < class T, void (std::conditional<std::is_class<T>::value, T, struct dummy>::type::* ...FUNC)(int)> class holder;

template < class T, void (T::*FUNC)(int)>
class holder<T, FUNC>
{
public:
    explicit holder() : setter(FUNC) { std::cout << "func\n"; }
private:
    std::function<void (value_type&, int)> setter;
};

template < class T>
class holder<T>
{
public:
    explicit holder() { std::cout << "plain\n"; }
};

よろしくお願いします!

PS: いいえ、「3 つ、4 つ、5 つのメンバー関数をどうする必要があるか」については、2 日以内に思いつきませんか? ;-)

4

2 に答える 2

0

ついに私は自分の問題の解決策を見つけました。これは、可変個引数テンプレートとテンプレートの仕様を組み合わせたものです。

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int) = nullptr,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::* ...FUNC2)(const std::string&)
>
class holder_ext;

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int),
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC2)(const std::string&)
>
class holder_ext<T, FUNC1, FUNC2>
{
public:
    holder_ext() { std::cout << "func 2 test\n"; }
};

template < class T,
void (std::conditional<std::is_base_of<object, T>::value, T, struct dummy>::type::*FUNC1)(int)
>
class holder_ext<T, FUNC1>
{
public:
    holder_ext() { std::cout << "func 1 test\n"; }
};

実装されていない宣言を使用し、2つの特殊化を定義します。1つはメンバー機能の両方を備え、もう1つは他のすべての場合に使用されます。

より良い解決策があれば、遠慮なく教えてください。

于 2012-12-11T10:00:55.847 に答える
0

完全に一般的な解決策の場合、解決できない問題にぶつかることになります。非型のテンプレート引数の型は推測できないため、テンプレート宣言で明示的に指定する必要があるため、テンプレートに必要なことを伝える方法はありません。複数のポインターからメンバーへの引数で、それぞれの型はまだ不明です。

私は C++11 で十分に遊んでいませんが、メンバー テンプレートの引数に順序付けを強制し、テンプレート内のすべての署名を提供してみてください。

template <typename T, 
          void (std::conditional<...>::type*)(int),
          void (std::conditional<...>::type*)(const std::string&)>

繰り返しますが、うまくいくかもしれませんし、うまくいかないかもしれません...

于 2012-12-07T14:07:55.703 に答える