我想用符合類型'void(ClassType :: Function)(ArgType)'的模板類來包裝成員函數。後來,我想類類別的一個實例傳遞給該模板的一個實例,並讓它調用包裝方法:在包裝<的實例C++ - 是否可以從模板中的成員函數類型中提取類和參數類型?
class Foo {
public:
Foo() : f_(0.0) {}
void set(double v) { f_ = v * 2.1; }
double get() { return f_; }
private:
double f_;
};
template <typename ArgType, typename ClassType, void (ClassType::*Method)(ArgType)>
class Wrapper {
public:
explicit Wrapper(ClassType *cls) : cls_(cls) {}
void do_something(ArgType value) {
(cls_->*Method)(value);
}
private:
ClassType *cls_;
};
#include <iostream>
int main(int argc, char ** argv) {
Foo foo;
Wrapper<double, Foo, &Foo::set> wrapper(&foo);
wrapper.do_something(1.0);
std::cout << foo.get() << std::endl;
// outputs "2.1"
return 0;
}
通知>說,「foo」被指定了兩次 - 它這裏看起來多餘。
所以我想知道的是是否有可能避免模板參數ClassType。例如,如果可以從成員函數指針參數中隱含或提取它,則它不需要在包裝器的實例化中明確指定>。因爲(可能)它可以從Foo :: set中確定,所以避免明確指定ArgType也是有用的。
這是可能的C++?也許東西沿着這些(完全幻想)線:
template <void (ClassType::*Method)(ArgType)>
class Wrapper2 {
public:
explicit Wrapper(Method::ClassType *cls) : cls_(cls) {}
void do_something(Method::ArgType value) {
(cls_->*Method)(value);
}
private:
Method::ClassType *cls_;
};
// ...
int main() {
Foo foo;
Wrapper<&Foo::set> wrapper(&foo);
// ...
}
或者,也許還有的模板魔術另一個層面可以被調用,會做沿着這些路線的東西:
Wrapper<Magic<&Foo::set> > wrapper(&foo);
我有興趣知道有什麼機制可用,如果有的話。
我使用C++ 03作爲需求,而不是C++ 11,但也有興趣知道C++ 11可能提供什麼。我打算使用這種機制來包裝300個成員函數(全部屬於ClassType或者一組非常相似的類),但是隻有大約6個左右的簽名需要考慮:
(編輯:更多信息)- 空隙(類類別::功能)(ArgType) - ,其中ArgType是 '浮動'
- 空隙(類類別::功能)(ArgType) - ,其中ArgType是 '積分'
- 空隙(類類別::函數)(bool)
- void(ClassType :: Function)(IndexType,ArgType) - 上面三個wi第一個額外的「索引」參數
成員函數是用於我所謂在大型結構「屬性」「集合」類,例如(而非上述簡單的Foo)「設置器」功能:
class MyPropertyCollection {
public:
void set_oink(double value) { oink_ = value; }
void set_bar(int value) { bar_ = value; }
void set_squee(bool value) { squee_ = value; }
private:
double oink_;
int bar_;
bool squee_;
};
// elsewhere
WrapperCollection wrapper_collection; // a simple set of wrapper objects, accessed by id
MyPropertyCollection property_collection;
wrapper_collection.add(PROPERTY_OINK_ID, new Wrapper<double, MyPropertySet, &MyPropertySet::set_oink>(&property_collection);
wrapper_collection.add(PROPERTY_BAR_ID, new Wrapper<int, MyPropertySet, &MyPropertySet::set_bar>(&property_collection);
wrapper_collection.add(PROPERTY_SQUEE_ID, new Wrapper<bool, MyPropertySet, &MyPropertySet::set_squee>(&property_collection);
// +300 more
我敢肯定,它將可能使用類專業化。由於扣除工作原理相反,因此您可以將方法聲明類型從僅包含一個的基本模板聲明中分解爲3個模板類型。噗,提取。我將立即在gcc中嘗試。 – 2015-03-06 05:03:08