在 C++ 中组合数据成员访问
Compose data member access in C++
我试图通过指向数据成员的指针迭代对象来访问数据成员。
想法是有一个可变参数模板函数,它在第一个 obj 上调用 std::invoke 并将结果传递给下一个指向数据成员的指针。
就像是
compose x fnList = foldl obj (\x f -> f x) fnList
来自函数世界。
我一路上得到的东西是:
// main.hpp
#include <iostream>
#include <functional>
// initial template to stop recursion
template<typename T>
T getMember(T obj) {
return obj;
}
// variadic template, where recursive application of
// pointer to data member should happen
// I think return type should be something like "*Ret"
template<typename T, typename K, typename Ret, typename ... Args>
Ret getMember(T obj, K memberPointer, Args ... args) {
return getMember(std::invoke(memberPointer, obj), args ...);
}
和
//main.cpp
#include <iostream>
#include "main.hpp"
//inner class
class Engine
{
public:
std::string name;
};
// outer class
class Car
{
public:
int speed;
Engine eng;
};
void main()
{
Car car;
car.speed = 1;
car.eng.name = "Some Engine Name";
// should be same as call to id function, returning the only argument
Car id = getMember(c1);
// should "apply" pointer to data member to the object and
// return speed of the car
int speedOfCar = getMember(car, &Car::speed);
// should "apply" pointer to data member to the car,
// pass the resulting Engine further to &Engine::name,
// return "Some Engine Name"
std::string nameOfEngineOfCar = getMember(car, &Car::eng, &Engine::name);
std::cout << nameOfEngineOfCar << std::endl;
}
编译无法推导出 return 类型 Ret
(gcc 5+,C++17)
有可能吗?有什么限制(可以在C++14中完成)吗?
您不能推导出只出现在函数 return 类型位置的模板参数。但是模板参数推导并不是 C++ 中唯一的一种推导。你可以这样做:
template <class Bar, class Baz>
auto foo(Bar x, Baz y)
-> decltype(auto) {
return moo(x, y);
}
如果由于旧编译器而失败,更安全的回退是
template <class Bar, class Baz>
auto foo(Bar x, Baz y)
-> decltype(moo(x, y)) {
return moo(x, y);
}
我试图通过指向数据成员的指针迭代对象来访问数据成员。
想法是有一个可变参数模板函数,它在第一个 obj 上调用 std::invoke 并将结果传递给下一个指向数据成员的指针。 就像是
compose x fnList = foldl obj (\x f -> f x) fnList
来自函数世界。
我一路上得到的东西是:
// main.hpp
#include <iostream>
#include <functional>
// initial template to stop recursion
template<typename T>
T getMember(T obj) {
return obj;
}
// variadic template, where recursive application of
// pointer to data member should happen
// I think return type should be something like "*Ret"
template<typename T, typename K, typename Ret, typename ... Args>
Ret getMember(T obj, K memberPointer, Args ... args) {
return getMember(std::invoke(memberPointer, obj), args ...);
}
和
//main.cpp
#include <iostream>
#include "main.hpp"
//inner class
class Engine
{
public:
std::string name;
};
// outer class
class Car
{
public:
int speed;
Engine eng;
};
void main()
{
Car car;
car.speed = 1;
car.eng.name = "Some Engine Name";
// should be same as call to id function, returning the only argument
Car id = getMember(c1);
// should "apply" pointer to data member to the object and
// return speed of the car
int speedOfCar = getMember(car, &Car::speed);
// should "apply" pointer to data member to the car,
// pass the resulting Engine further to &Engine::name,
// return "Some Engine Name"
std::string nameOfEngineOfCar = getMember(car, &Car::eng, &Engine::name);
std::cout << nameOfEngineOfCar << std::endl;
}
编译无法推导出 return 类型 Ret
(gcc 5+,C++17)
有可能吗?有什么限制(可以在C++14中完成)吗?
您不能推导出只出现在函数 return 类型位置的模板参数。但是模板参数推导并不是 C++ 中唯一的一种推导。你可以这样做:
template <class Bar, class Baz>
auto foo(Bar x, Baz y)
-> decltype(auto) {
return moo(x, y);
}
如果由于旧编译器而失败,更安全的回退是
template <class Bar, class Baz>
auto foo(Bar x, Baz y)
-> decltype(moo(x, y)) {
return moo(x, y);
}