今天,我寫了一些代碼,需要根據模板參數的類型將元素添加到不同的容器變量。我通過編寫一個專門用於自己的模板參數的朋友幫助類來解決這個問題,該參數有一個原始類的成員變量。它爲我節省了幾百行重複自己的工作,而不會增加很多複雜性。然而,它似乎是kludgey。我想知道是否有更好,更優雅的方式。更好的方法來使C++成員函數根據模板參數改變不同的成員變量?
下面的代碼是一個非常簡化的例子,說明了問題和我的解決方案。它用g ++編譯。
#include <vector>
#include <algorithm>
#include <iostream>
namespace myNS{
template<class Elt>
struct Container{
std::vector<Elt> contents;
template<class Iter>
void set(Iter begin, Iter end){
contents.erase(contents.begin(), contents.end());
std::copy(begin, end, back_inserter(contents));
}
};
struct User;
namespace WkNS{
template<class Elt>
struct Worker{
User& u;
Worker(User& u):u(u){}
template<class Iter>
void set(Iter begin, Iter end);
};
};
struct F{ int x; explicit F(int x):x(x){} };
struct G{ double x; explicit G(double x):x(x){} };
struct User{
Container<F> a;
Container<G> b;
template<class Elt>
void doIt(Elt x, Elt y){
std::vector<Elt> v; v.push_back(x); v.push_back(y);
Worker<Elt>(*this).set(v.begin(), v.end());
}
};
namespace WkNS{
template<class Elt> template<class Iter>
void Worker<Elt>::set(Iter begin, Iter end){
std::cout << "Set a." << std::endl;
u.a.set(begin, end);
}
template<> template<class Iter>
void Worker<G>::set(Iter begin, Iter end){
std::cout << "Set b." << std::endl;
u.b.set(begin, end);
}
};
};
int main(){
using myNS::F; using myNS::G;
myNS::User u;
u.doIt(F(1),F(2));
u.doIt(G(3),G(4));
}
User
是我寫的課。
Worker
是我的助手類。我在它自己的命名空間中使用它,因爲我不希望它在myNS之外造成麻煩。
Container
是一個容器類,其定義我不想修改,但在其實例變量中使用User
。
doIt<F>
應該修改一個。 doIt<G>
應該修改b。
F
和G
只對有限的修改開放,如果這會產生更優雅的解決方案。 (作爲一個這樣的修改的一個例子,在實際應用中F
的構造需要一個僞參數,以使其看起來像G
的構造和保存箱從重複自己。)
在實際代碼,Worker
是一個User
的朋友和成員變量是私人的。爲了讓這個例子更容易寫,我公開了一切。然而,要求事物公開的解決方案並不能回答我的問題。
鑑於所有這些警告,有沒有更好的方法來編寫User::doIt
?
爲什麼不只是有一個非模板'User :: doIt'成員函數爲'F'和'G'重載? – 2010-06-01 23:35:23
真正的'User :: doIt'是複雜的(它對多維插值例程進行預計算)並且對a和b幾乎完成相同的事情,主要區別在於使用F和G對象的適當成員函數。該模板避免了複製/粘貼重複代碼。 – Eponymous 2010-06-02 00:37:51