在 C++ 中将任意就地运算符转换为一元运算符
Convert an arbitrary in place operator to a unary operator in C++
std::transform()
采用对某种类型 T 进行操作的一元运算符。它应该看起来像 T f(T&)
。有时我们使用一个不合适的函数,例如 boost::algorithm::to_lower()
which returns void 并且是一种接受多个参数的类型(尽管其他参数是默认的)。我可以像这样转换 boost::algorithm::to_lower()
struct tl {
template<typename T>
T operator()(T &v) const {
boost::algorithm::to_lower(v);
return v;
}
};
并使用这个
tl low;
std::vector<...> vec;
...
std::transform(vec.begin(), vec.end(), vec.begin(), low);
我想做的是进一步推广这一步;让 f()
成为一个函数,接受一个 T&
类型的参数,可能还有多个其他参数,这些参数必须具有默认值并返回任意类型(可以是 T,可以是 void,可以是其他东西,我们只是假设它作用于传递的参考值。进一步 f
本身可能是模板,因为 boost::algorithm::to_lower() 是。我想做一些人们可能期望
tl<decltype f> low(f);
做完就可以打电话了
std::transform(vec.begin(), vec.end(), vec.begin(), low);
这样我就不会为每个要转换的函数编写 class。显然 decltype(f) 在这里不起作用。 C++11 是首选,但如果需要 14 或 17 也没关系。
试试下面的宏:
#define MAKE_FUNCTIONAL( f ) []( auto x ){ f(x); return x; }
你可以这样使用它:
std::transform( vec.begin(), vec.end(), vec.begin(),
MAKE_FUNCTIONAL(boost::algorithm::to_lower) );
这会非常有效。 :) 这需要 C++14,因为它使用带有自动参数的 lambda。
std::transform()
采用对某种类型 T 进行操作的一元运算符。它应该看起来像 T f(T&)
。有时我们使用一个不合适的函数,例如 boost::algorithm::to_lower()
which returns void 并且是一种接受多个参数的类型(尽管其他参数是默认的)。我可以像这样转换 boost::algorithm::to_lower()
struct tl {
template<typename T>
T operator()(T &v) const {
boost::algorithm::to_lower(v);
return v;
}
};
并使用这个
tl low;
std::vector<...> vec;
...
std::transform(vec.begin(), vec.end(), vec.begin(), low);
我想做的是进一步推广这一步;让 f()
成为一个函数,接受一个 T&
类型的参数,可能还有多个其他参数,这些参数必须具有默认值并返回任意类型(可以是 T,可以是 void,可以是其他东西,我们只是假设它作用于传递的参考值。进一步 f
本身可能是模板,因为 boost::algorithm::to_lower() 是。我想做一些人们可能期望
tl<decltype f> low(f);
做完就可以打电话了
std::transform(vec.begin(), vec.end(), vec.begin(), low);
这样我就不会为每个要转换的函数编写 class。显然 decltype(f) 在这里不起作用。 C++11 是首选,但如果需要 14 或 17 也没关系。
试试下面的宏:
#define MAKE_FUNCTIONAL( f ) []( auto x ){ f(x); return x; }
你可以这样使用它:
std::transform( vec.begin(), vec.end(), vec.begin(),
MAKE_FUNCTIONAL(boost::algorithm::to_lower) );
这会非常有效。 :) 这需要 C++14,因为它使用带有自动参数的 lambda。