Hoo*_*ked 1 c++ templates stl c++11
通过以前的答案阅读,我觉得我可能有设计问题,但即使答案是学术性的,我仍然想知道是否有可能.我已经用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; }
}
Run Code Online (Sandbox Code Playgroud)
我想要的是看起来像下面的伪代码:
template<class T, class U, class N>
void set_parameter(T &S, U val) {
for(auto &x: S) { x.N = val; }
}
Run Code Online (Sandbox Code Playgroud)
我可以这样称呼它set_parameter(foo, 2.0, "epsilon"),编译器会set_parameter_epsilon自动创建函数.虽然我确信提升可以做到这一点,但如果可能的话,我更愿意看到仅限STL的版本.
哎呀原来我错过了在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";
}
Run Code Online (Sandbox Code Playgroud)
哪些版画(Live on 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
Run Code Online (Sandbox Code Playgroud)
#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);
}
Run Code Online (Sandbox Code Playgroud)
这充满了细微差别.但足以说,它按照要求"有效":
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
3.14, hello world
Run Code Online (Sandbox Code Playgroud)
为了增加精神错乱:请注意,通过返回有用的值,您可以做更多...有趣的事情,仍然:
return set_parameter(
set_parameter(X(), 3.14, &X::foo),
"hello world", &X::splurgle)
.splurgle.length();
Run Code Online (Sandbox Code Playgroud)