result_of<> ::类型应用于成员指针

时间:2016-01-21 20:24:56

标签: c++ c++11

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>

问题:

  1. 如果自动返回类型扣除不可用,如何使fooClass编译?
  2. 更大的问题是:如何编写一个带有类型A的任意迭代器(wrt iterator_category)的枚举器,将它包装并转换为类型B的迭代器(与源迭代器属于同一类别)并结合使用成员字段,成员函数或正常函数。 C#等价物将是IEnumerable<B> IEnumerable<A>.Select(Func<A, B> f)

0 个答案:

没有答案