#include <iostream>
#include <functional>
#include <vector>
namespace detail
{
using std::begin;
using std::end;
template <typename Container, typename F>
auto RetrieveTransformation(const Container& c, F f)
-> std::vector<std::decay_t<decltype(f(*begin(c)))>>
{
// if `F` return `const T&`, we want `std::vector<T>`,
// so we remove reference and cv qualifier with `decay_t`.
//
// That handles additionally the case of lambda
// The return type of lambda [](const std::string&s) { return s;}
// - is `const std::string` for msvc
// - is `std::string` for for gcc
// (Note that the return type rules have changed:
// see http://w...content-available-to-author-only...d.org/jtc1/sc22/wg21/docs/cwg_defects.html#1048)
using F_Ret = std::decay_t<decltype(f(*begin(c)))>;
std::vector<F_Ret> res;
res.reserve(std::distance(begin(c), end(c)));
for (const auto& e : c)
{
res.push_back(f(e));
}
return res;
}
}
template <typename Container, typename F>
auto RetrieveTransformation(const Container& c, F f)
-> decltype(detail::RetrieveTransformation(c, f))
{
return detail::RetrieveTransformation(c, f);
}
struct A
{
int color;
A(int p_f) : color(p_f) {}
int getColor() const { return color; }
};
int main ()
{
A la[4] = {A(3),A(5),A(2),A(1)};
std::vector<int> lv = RetrieveTransformation(la, std::mem_fn(&A::getColor));
for (const auto& e : lv) std::cout << ' ' << e;
std::cout << std::endl;
for (const auto& e : RetrieveTransformation(la, [](const A&a){return a.color;})) std::cout << ' ' << e;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHZlY3Rvcj4KCm5hbWVzcGFjZSBkZXRhaWwKewogICAgdXNpbmcgc3RkOjpiZWdpbjsKICAgIHVzaW5nIHN0ZDo6ZW5kOwogICAgCgl0ZW1wbGF0ZSA8dHlwZW5hbWUgQ29udGFpbmVyLCB0eXBlbmFtZSBGPgoJYXV0byBSZXRyaWV2ZVRyYW5zZm9ybWF0aW9uKGNvbnN0IENvbnRhaW5lciYgYywgRiBmKQoJICAgIC0+IHN0ZDo6dmVjdG9yPHN0ZDo6ZGVjYXlfdDxkZWNsdHlwZShmKCpiZWdpbihjKSkpPj4KCXsKCSAgICAvLyBpZiBgRmAgcmV0dXJuIGBjb25zdCBUJmAsIHdlIHdhbnQgYHN0ZDo6dmVjdG9yPFQ+YCwKCSAgICAvLyBzbyB3ZSByZW1vdmUgcmVmZXJlbmNlIGFuZCBjdiBxdWFsaWZpZXIgd2l0aCBgZGVjYXlfdGAuCgkgICAgLy8KCSAgICAvLyBUaGF0IGhhbmRsZXMgYWRkaXRpb25hbGx5IHRoZSBjYXNlIG9mIGxhbWJkYQoJICAgIC8vIFRoZSByZXR1cm4gdHlwZSBvZiBsYW1iZGEgW10oY29uc3Qgc3RkOjpzdHJpbmcmcykgeyByZXR1cm4gczt9CgkgICAgLy8gLSBpcyBgY29uc3Qgc3RkOjpzdHJpbmdgIGZvciBtc3ZjCgkgICAgLy8gLSBpcyBgc3RkOjpzdHJpbmdgIGZvciBmb3IgZ2NjCgkgICAgLy8gKE5vdGUgdGhhdCB0aGUgcmV0dXJuIHR5cGUgcnVsZXMgaGF2ZSBjaGFuZ2VkOgoJICAgIC8vIHNlZSBodHRwOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9jd2dfZGVmZWN0cy5odG1sIzEwNDgpCgkgICAgdXNpbmcgRl9SZXQgPSBzdGQ6OmRlY2F5X3Q8ZGVjbHR5cGUoZigqYmVnaW4oYykpKT47CgkgICAgc3RkOjp2ZWN0b3I8Rl9SZXQ+IHJlczsKCSAgICByZXMucmVzZXJ2ZShzdGQ6OmRpc3RhbmNlKGJlZ2luKGMpLCBlbmQoYykpKTsKCSAgICBmb3IgKGNvbnN0IGF1dG8mIGUgOiBjKQoJICAgIHsKCSAgICAgICAgcmVzLnB1c2hfYmFjayhmKGUpKTsKCSAgICB9CgkgICAgcmV0dXJuIHJlczsKCX0KCn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBDb250YWluZXIsIHR5cGVuYW1lIEY+CmF1dG8gUmV0cmlldmVUcmFuc2Zvcm1hdGlvbihjb25zdCBDb250YWluZXImIGMsIEYgZikKLT4gZGVjbHR5cGUoZGV0YWlsOjpSZXRyaWV2ZVRyYW5zZm9ybWF0aW9uKGMsIGYpKQp7CglyZXR1cm4gZGV0YWlsOjpSZXRyaWV2ZVRyYW5zZm9ybWF0aW9uKGMsIGYpOwp9CgpzdHJ1Y3QgQQp7CiAgICBpbnQgY29sb3I7CgogICAgQShpbnQgcF9mKSA6IGNvbG9yKHBfZikge30KICAgIAogICAgaW50IGdldENvbG9yKCkgY29uc3QgeyByZXR1cm4gY29sb3I7IH0KfTsKCmludCBtYWluICgpCnsgIAogIEEgbGFbNF0gPSB7QSgzKSxBKDUpLEEoMiksQSgxKX07CiAgc3RkOjp2ZWN0b3I8aW50PiBsdiA9IFJldHJpZXZlVHJhbnNmb3JtYXRpb24obGEsIHN0ZDo6bWVtX2ZuKCZBOjpnZXRDb2xvcikpOwogIGZvciAoY29uc3QgYXV0byYgZSA6IGx2KSBzdGQ6OmNvdXQgPDwgJyAnIDw8IGU7CiAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICBmb3IgKGNvbnN0IGF1dG8mIGUgOiBSZXRyaWV2ZVRyYW5zZm9ybWF0aW9uKGxhLCBbXShjb25zdCBBJmEpe3JldHVybiBhLmNvbG9yO30pKSBzdGQ6OmNvdXQgPDwgJyAnIDw8IGU7Cn0=