我只是將用於構造T的參數添加爲Container的模板參數,並使用它們構造T.爲了允許T對象的動態構造,容器構造函數接受作爲參數的函數指針爲參數的創建排名的整數,並且對於T構造的默認參數,並返回參數的元組對於T構造(std::tuple<U...> (*getInitParam)(int rank, U... params)
):
template<typename T, typename ...U>
class Container {
struct Wrapper {
T mType;
int mInfo;
Wrapper(int mInfo, U... params): mType(params...), mInfo(mInfo) {}
};
std::stack<Wrapper *> stack;
int get_mInfo() {
static int info = 0;
return info++;
}
std::tuple<U...> (*getInitParam)(int rank, U... params);
public:
T* pop() {
// should control stack is not empty
Wrapper *w = stack.top();
stack.pop();
return &w->mType;
}
void push(T* type) {
char *p = reinterpret_cast<char *>(type);
p -= offsetof(Wrapper, mType);
Wrapper *w = reinterpret_cast<Wrapper *>(p);
// would need to control that *w is a valid Wrapper
stack.push(w);
}
void init(int n, U... params) {
std::tuple<U...> orig = std::make_tuple(params...);
for (int i=0; i<n; i++) {
if (getInitParam != nullptr) {
std::tie(params...) = orig;
std::tuple<U...> tparams = (*getInitParam)(i, params...);
std::tie(params...) = tparams;
}
Wrapper *w = new Wrapper(get_mInfo(), params...);
stack.push(w);
}
}
Container(std::tuple<U...> (*getInitParam)(int rank, U... params) = nullptr)
: getInitParam(getInitParam) {}
~Container() {
while(! stack.empty()) {
Wrapper *w = stack.top();
delete w;
stack.pop();
}
}
};
用例:
std::tuple<size_t, char> doInit(int i, size_t szmin, char c) {
return std::make_tuple(szmin + i, c);
}
int main() {
Container<std::string, size_t, char> cont(&doInit);
cont.init(10, 5, 'x');
std::string* str0 = cont.pop();
std::string* str = cont.pop();
std::cout << *str0 << std::endl;
std::cout << *str << std::endl;
*str0 = "bar";
cont.push(str0);
cont.push(str);
str0 = cont.pop();
str = cont.pop();
std::cout << *str << std::endl;
cont.push(str);
cont.push(str0);
return 0;
}
Ť他正確地輸出:
xxxxxxxxxxxxxx
xxxxxxxxxxxxx
bar
仍然有實行明覆用法,但它應該是一個起點......
最好是寫代碼,然後解釋類應該做的事情。爲什麼要創建實例,如果有可能推/流? –
只能推動/彈出屬於容器的對象。也就是說,容器需要附加信息進行裝飾的對象。用戶看到T *,而容器看到Wrapper *。 – user1715664
我同意BЈовић:最好是寫代碼。但是,從我所能理解的情況來看,你需要一個包裝器中的構造函數,它需要你的T. – noxmetus