在 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。