2013-03-04 97 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); 
    } 
} 
相關問題