将默认值列表传递给模板类

时间:2016-08-15 12:08:59

标签: c++ templates

不确定是否可以使用模板完成,但我想尝试一下。

我有一个模板类,它接受任何结构,存储它并返回它。另外,我想要一个可以在需要时重置结构数据的接口。

#define MYDEFAULT {1,2,3}

template < typename ITEM, ITEM Default>
class myClass{
public:
    myClass(ITEM item) : _item(item) {}

    const ITEM* get(){
        return &_item;
    }

    void reset(){
        _item = Default;
    }

    ITEM _item;
};
// Set to default when instantiated
myClass<myStruct, MYDEFAULT> ABC(MYDEFAULT);

当然这根本不起作用,但我想要实现的是替换Default中的reset()。我的意思是如果_item属于int类型,它会起作用 怎么能实现呢?

编辑:我想要这样的事情:

template <typename Y, Y T>
class myclass {
public:
void reset() {
    xxx = T;
}
    Y xxx{10};
};


void test()
{
    myclass<int, 5> _myclass;
}

最初xxx是10并且在调用reset之后它是5.这是有效的,所以它似乎不可能用于POD或类类型?

EDIT2:似乎所有关于非类型模板参数。 https://stackoverflow.com/a/2183121/221226 因此,使用结构时无法绕过特征。

2 个答案:

答案 0 :(得分:2)

作为一个可行的解决方案,您可以使用特征类,如以下工作示例所示:

#include<cassert>

struct S {
    int i;
};

template<typename T>
struct Traits {
    static constexpr auto def() { return T{}; }
};

template<>
struct Traits<S> {
    static constexpr auto def() { return S{42}; }
};

template <typename ITEM>
class myClass {
public:
    myClass(): _item(Traits<ITEM>::def()) {}
    myClass(ITEM item): _item(item) {}

    const ITEM* get() {
        return &_item;
    }

    void reset() {
        _item = Traits<ITEM>::def();
    }

    ITEM _item;
};

int main() {
    myClass<S> ABC{};
    myClass<int> is;
    assert((ABC.get()->i == 42));
    assert((*is.get() == 0));
}

基本特征使用ITEM类型的默认构造函数 然后,只要您想为特定类别设置不同的默认值,就可以对其进行专门化。

即使使用工厂功能,也可以实现相同的目的:

template<typename T>
constexpr auto def() { return T{}; }

template<>
constexpr auto def<S>() { return S{42}; }

无论如何,特征可以很容易地同时提供更多的类型和功能。

答案 1 :(得分:0)

您可以使用数据成员std::array的数据结构来模拟它 最小的工作示例如下:

#include<cstddef>
#include<array>
#include<cassert>

template<typename T, T... I>
struct S {
    S(): arr{ I... } {}

    S(const T (&val)[sizeof...(I)]) {
        for(std::size_t i = 0; i < sizeof...(I); ++i) {
            arr[i] = val[i];
        }
    }

    const T * get() {
        return arr.data();
    }

    void reset() {
        arr = { I... };
    }

private:
    std::array<T, sizeof...(I)> arr;
};

int main() {
    S<int, 1, 3, 5> s{{ 0, 1, 2 }};
    assert(s.get()[1] == 1);
    s.reset();
    assert(s.get()[1] == 3);
}

我不确定我到底要求的是什么,但示例中的界面接近问题中的界面,实施细节不应影响您班级的用户。