[英]C++ overloading by functor param count type
我正在為C ++ 11開發“LINQ to Objects”庫。 我想像這樣做:
// filtering elements by their value
arr.where( [](double d){ return d < 0; } )
// filtering elements by their value and position
arr.where( [](double d, int i){ return i%2==0; } )
我想寫arr.where_i( ... )
- 這很難看。 所以我需要lambda類型的函數/方法重載...
這是我的解決方案:
template<typename F>
auto my_magic_func(F f) -> decltype(f(1))
{
return f(1);
}
template<typename F>
auto my_magic_func(F f, void * fake = NULL) -> decltype(f(2,3))
{
return f(2,3);
}
int main()
{
auto x1 = my_magic_func([](int a){ return a+100; });
auto x2 = my_magic_func([](int a, int b){ return a*b; });
// x1 == 1+100
// x2 == 2*3
}
是SFINAE解決方案嗎? 你有什么建議我的?
也許是可變的東西:
#include <utility>
template <typename F, typename ...Args>
decltype(f(std::declval<Args>()...) my_magic_func(F f, Args &&... args)
{
return f(std::forward<Args>(args)...);
}
編輯:您還可以使用typename std::result_of<F(Args...)>::type
作為返回類型,它執行相同的操作。
您當然希望SFINAE在您的解決方案中。 一般來說,結果看起來像:
template<
typename Functor
, typename std::enable_if<
special_test<Functor>::value
, int
>::type = 0
>
return_type
my_magic_func(Functor f);
template<
typename Functor
, typename std::enable_if<
!special_test<Functor>::value
, int
>::type = 0
>
return_type
my_magic_func(Functor f);
這樣在任何時候只有一個重載是活動的 - 現在剩下的就是精心設計special_test
以獲得我們想要的行為。 這是一個謹慎的平衡行為,因為您不希望測試過於具體; 否則我們會失去普遍性。 編寫通用代碼時非常遺憾。 你沒有給出太多的信息(例如你是否對lambdas?單態函子?多態函子?)有嚴格的興趣,但我現在假設我們可以訪問一個value_type
別名,它對應於你的例子中的double
。
因此,這是一個示例條件,它將使用簽名bool(value_type)
檢查給定類型是否可調用(這是標准概念bool(value_type)
; 即它是各種類型的謂詞:
template<typename Functor, typename ValueType>
struct is_unary_predicate {
typedef char (&accepted)[1];
typedef char (&refused)[2];
void consume(bool);
template<
typename X
, typename Y
, typename = decltype( consume(std::declval<X>()(std::declval<Y>())) )
>
accepted
test(X&&, Y&&);
refused test(...);
static constexpr bool value =
sizeof test(std::declval<Functor>(), std::declval<ValueType>())
== sizeof(accepted);
};
我個人有一個is_callable<F, Signature>
trait,所以我只需要template<typename Functor, typename ValueType> using is_unary_predicate = is_callable<Functor, bool(ValueType)>;
寫一些類似template<typename Functor, typename ValueType> using is_unary_predicate = is_callable<Functor, bool(ValueType)>;
(同樣我可以有一個is_binary_predicate
別名,而不是讓my_magic_func
的第二次重載成為一個全能的)。 也許你想在SFINAE的未來使用中使用類似的特性(盡管在沒有可變參數模板的情況下編寫可能有點痛苦)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.