模板化一个类似python的setattr函数
Template a python-like setattr function
通读以前的答案,我觉得我可能有设计问题,但即使答案是学术性的,我仍然想知道这是否可能。我用Python编程已经有一段时间了,它显示了这一点。我正在尝试在对象上创建类似setattr
访问的东西。用手看,它看起来像:
template<class T, class U>
void set_parameter_sigma(T &S, U val) {
for(auto &x: S) { x.sigma = val; }
}
template<class T, class U>
void set_parameter_epsilon(T &S, U val) {
for(auto &x: S) { x.epsilon = val; }
}
template<class T, class U>
void set_parameter_length(T &S, U val) {
for(auto &x: S) { x.length = val; }
}
我想要的是看起来像以下伪代码的东西:
template<class T, class U, class N>
void set_parameter(T &S, U val) {
for(auto &x: S) { x.N = val; }
}
我可以像set_parameter(foo, 2.0, "epsilon")
那样调用它,编译器会自动创建set_parameter_epsilon
函数。虽然我确信boost可以做到这一点,但如果可能的话,我更希望看到STL版本。
更新:
Oops原来我错过了在setter内循环容器元素的要求。那么,让我修正一下我的错误:
#include <utility>
template <class C, class U, class U2 /* assignable from U*/,
class T = typename C::value_type>
void set_parameter(C& container, U&& val, U2 (T::* pmember), typename C::value_type* sfinae=nullptr)
{
for (auto& instance : container)
(instance.*(pmember)) = std::forward<U>(val);
}
#include <iostream>
#include <string>
#include <vector>
struct X
{
double foo;
std::string splurgle;
};
int main()
{
std::vector<X> xs(10);
set_parameter(xs, 42, &X::foo);
set_parameter(xs, "hello world", &X::splurgle);
for (auto const& x : xs)
std::cout << x.foo << ", " << x.splurgle << "n";
}
哪个打印(在Coliru上直播)
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
42, hello world
原始答案文本:
#include <utility>
#include <type_traits>
template <class T, class U, class U2 /* assignable from U*/, class T2 = typename std::remove_reference<T>::type>
T&& set_parameter(T&& instance, U&& val, U2 (T2::* pmember))
{
(instance.*(pmember)) = std::forward<U>(val);
return std::forward<T>(instance);
}
这里面充满了细微差别。但可以说,它按照要求"工作":
#include <iostream>
#include <string>
struct X
{
double foo;
std::string splurgle;
};
int main()
{
X x;
set_parameter(x, 3.14 , &X::foo);
set_parameter(x, "hello world", &X::splurgle);
std::cout << x.foo << ", " << x.splurgle;
}
输出:
3.14, hello world
对于额外的疯狂:请注意,通过返回有用的值,你可以做更多。。。有趣的事情,仍然:
return set_parameter(
set_parameter(X(), 3.14, &X::foo),
"hello world", &X::splurgle)
.splurgle.length();
您可能可以使用指向成员的指针,但我不确定您是否会喜欢:
struct XX
{
char c;
int i;
};
template<class T, class U, class N>
void set_parameter(T &S, U val, N T::*n) {
for(auto &x: S) { x.*n = val; }
}
set_parameter(..., ..., &XX::c);
set_parameter(..., ..., &XX::i);
相关文章:
- 使用C++指针调用 python 函数
- 使用 pybind11 调用 Python 函数时避免复制输入数据
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 如何使用 pybind11 将 python 函数保存到静态 c++ 容器中?
- 在 cpp 中嵌入 python:如何获取指向 python 函数(而不是 PyObject)的 C 指针?
- 困在PyObject_GetAttrString():如何从C++代码中获取Python函数脚本
- 如何通过C++在Python函数中传递字符串参数
- 在 C 代码中调用 Python 函数时第三次出现访问冲突写入位置错误
- 通过 Boost Python 将 Python 函数转换为 C++,用作回调
- 获取 C++ 中的 Python 函数参数名称
- 使用来自C++的任意数量的参数(在编译时未知)调用 Python 函数
- 如何从Qt C++项目运行Python函数
- 如何从 c++ 调用另一个文件中定义的 python 函数?
- 无法理解提升 python 函数导出中的语法
- 执行 c++ 中字符串中提供的 Python 函数
- 使用 pybind11 从 C++ 调用 Python 函数
- 从C 中的多个线程调用Python函数
- 使用 C++ 中的 python 函数
- 如何使用 pybind11 将 python 函数转换为 std::function
- TensorFlow:可用的Python函数的C++等价物