2013-03-04 66 views
10

作为一个懒惰的开发者,我喜欢用这种伎俩来指定一个默认功能:刚刚返回传递值的默认函数?

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*/

回答

19

没有标准的函子,做这很容易写出来(尽管具体形式有争议):

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); 
    } 
} 
+3

+1,而是将'Function()'作为默认参数,而不是'identity()'。 – 2013-03-04 17:13:48

+0

@ChristianRau:好点。 – Mankarse 2013-03-05 01:03:38

+0

为什么你在这里使用一个结构?为什么不把“身份”定义为一个函数呢? – Claudiu 2014-11-14 21:33:45

1

这被称为identity函数。不幸的是,它不是C++标准的一部分,但你可以自己轻松构建一个。

如果你碰巧使用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); 
    } 
} 
+0

在这里,默认参数应该可能是'Function()'(即使'Function'不是_'__gnu_cxx :: identity '),它也可以工作。 – jogojapan 2013-03-05 01:30:58

1

您只需建立自己的身份的仿函数:

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); 
    } 
} 
+2

仅移动类型失败。 – Puppy 2013-03-04 13:24:57

+0

@DeadMG谢谢你,好评,我用我认为最低要求编辑了我的答案,如果能解决所有问题,你能不能让我知道。我应该使用'forward'而不是'move'吗? – 2013-03-04 13:54:06

2

的boost ::凤凰提供了一个完整的功能工具箱,在这里 'ARG1' 是的ident身份;-)

#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); 
    } 
} 
相关问题