更新:
糟糕,原来我错过了在 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();