template<class C, class F>
struct _fooClass {
const C& obj_; // any class
const F& fn_; // pointer to member field of C
_fooClass(C& obj, F fn) : obj_(obj), fn_(fn) {}
auto operator()() -> decltype(obj_.*fn_) {
return obj_.*fn_; // returns the value stored in this member
}
// declare an operator that converts
// _fooClass to decltype(obj_.*fn_)
};
template<class C, class F>
//
// version 1: let compiler deduce the type
// auto fooClass(C obj, const F& fn)
// result: compiles
//
// version 2: explicit write down the type b/c compiler hasn't implemented auto return type deduction
// auto fooClass(C obj, const F& fn) -> typename std::result_of<decltype(fn)(C)>::type
// result: error (g++) cannot bind 'const int' lvalue to 'std::__success_type<int&&>::type {aka int&&}'
// error (VC) cannot convert const int to int&
//
auto fooClass(C obj, const F& fn) -> typename std::result_of<decltype(fn)(C)>::type {
_fooClass<C, F> c(obj, fn);
return c();
}
int main(int argc, char **argv)
{
const B b{1};
//auto x = foo(b, &B::field2);
auto x = fooClass(b, &B::field2);
std::cout << x << std::endl;
return 0;
}
背景:_fooClass最终应该成为迭代器的一部分变换器。例如,
struct B {
int field1;
}
template<class Enumerator>
void user_function(Enumerator e) {
for (auto i : e) {
}
}
// what's the return type?
template<class CONTAINER, class F>
auto enumerate(CONTAINER& c, F fn) {
return ....; // create an enumerator
}
void main() {
vector<B> vec;
user_function(enumerate(b, &b::field1));
}
user_function
采用某种类型的任意枚举器,枚举器后面的源代码来自vector<B>
。
问题:
IEnumerable<B> IEnumerable<A>.Select(Func<A, B> f)