Функция по умолчанию, которая возвращает только прошедшее значение?
Как ленивый разработчик, мне нравится использовать этот трюк, чтобы указать функцию по умолчанию:
template <class Type, unsigned int Size, class Function = std::less<Type> >
void arrange(std::array<Type, Size> &x, Function&& f = Function())
{
std::sort(std::begin(x), std::end(x), f);
}
Но у меня есть проблема в очень конкретном случае, которая заключается в следующем:
template <class Type, unsigned int Size, class Function = /*SOMETHING 1*/>
void index(std::array<Type, Size> &x, Function&& f = /*SOMETHING 2*/)
{
for (unsigned int i = 0; i < Size; ++i) {
x[i] = f(i);
}
}
В этом случае я хотел бы, чтобы функция по умолчанию была эквивалентной: [](const unsigned int i){return i;}
(функция, которая просто возвращает переданное значение).
Чтобы сделать это, что мне нужно написать вместо /*SOMETHING 1*/
и /*SOMETHING 2*/
?
Ответы
Ответ 1
Нет стандартного функтора, который делает это, но его достаточно легко написать (хотя конкретная форма для некоторого спора):
struct identity {
template<typename U>
constexpr auto operator()(U&& v) const noexcept
-> decltype(std::forward<U>(v))
{
return std::forward<U>(v);
}
};
Это можно использовать следующим образом:
template <class Type, std::size_t Size, class Function = identity>
void index(std::array<Type, Size> &x, Function&& f = Function())
{
for (unsigned int i = 0; i < Size; ++i) {
x[i] = f(i);
}
}
Ответ 2
boost:: phoenix предлагает полный функциональный набор инструментов, здесь 'arg1' является идентификатором идентификатора; -)
#include <boost/phoenix/core.hpp>
template <class X, class Function = decltype(boost::phoenix::arg_names::arg1)>
void index(X &x, Function f = Function()) {
for (std::size_t i = 0; i < x.size(); ++i) {
x[i] = f(i);
}
}
Ответ 3
Это называется identity
. К сожалению, он не является частью стандарта С++, но вы можете легко создать его самостоятельно.
Если вы используете g++, вы можете активировать его расширения с помощью -std=gnu++11
, а затем
#include <array>
#include <ext/functional>
template <class Type, std::size_t Size, class Function = __gnu_cxx::identity<Type> >
void index(std::array<Type, Size> &x, Function&& f = __gnu_cxx::identity<Type>())
{
for (unsigned int i = 0; i < Size; ++i) {
x[i] = f(i);
}
}
Ответ 4
Вы можете просто создать свой собственный функтор идентификации:
template <typename T>
class returnIdentifyFunctor
{
public:
auto operator ()( T &&i ) -> decltype( std::forward<T>(i) )
{
return std::move(i);
}
};
template <class Type, unsigned int Size, class Function = returnIdentifyFunctor<Type>>
void index(std::array<Type, Size> &x, Function&& f = Function() )
{
for (unsigned int i = 0; i < Size; ++i) {
x[i] = f(i);
}
}