4

次の作業コードがあります。

class person
{
private:
    int age_;
public:
    person() : age_(56) {}
    void age(int a) { age_ = i; }
}

template < class T, void (T::* ...FUNC)(int) > class holder;

template < class T, void (T::*FUNC)(int)>
class holder<T, FUNC>
{
public:
    typedef typename T::value_type value_type;
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"; }
};

int main()
{
    holder<person> h1;
    holder<person, &person::age> h2;

    // this does not work:
    holder<int> h3;
}

int (またはその他の非クラス、構造体、または共用体型) の場合、2 番目のテンプレート引数のメンバー関数が予期されるため、コードが機能しないことを私は知っています。

私の質問は、コードを変更して機能させる方法です。ホルダークラスを簡単に使用できるようにするために、そのように機能する必要があります。

型の特徴で試してみましたが、メンバー関数ポインターをクラスのコンストラクターに移動しました。成功せずに。

助言がありますか?前もって感謝します!

4

1 に答える 1

3

更新:私はそれを動作させることができましたstd::conditional

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 class_holder
{
public:
    typedef typename T::value_type value_type;
public:
    explicit class_holder() : setter(FUNC) { std::cout << "func\n"; } 
protected:
    std::function<void (value_type&, int)> setter;
}

template <class T, bool IsClass = std::is_class<T>::value>
class holder;

template <class T>
class holder<T, true> : public class_holder<T>
{
public:
    template <void (T::*FUNC)(int) >
    class with_member : public class_holder<T, FUNC>
    {
    };
};

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

int main()
{
    holder<person> h1;
    holder<person>::with_member<&person::age> h2;
    holder<int> h3;
}

私はこれをコンパイルしていないので、何かがうまくいかないかどうか教えてください。

于 2012-12-05T09:39:35.173 に答える