2017-08-02 90 views
2

我正在嘗試使用C++ 14元編程來查找lambda函數或自由函數是否爲常量。查找函數是否爲

我目前的策略是在每個參數上使用std::is_reference,std::is_pointerstd::is_const。 (目前,忽略了全局變量...)

使檢查對象類型看起來是這樣的......

template <typename F> 
struct is_const_func: public function_traits<decltype(&F::operator())> {}; 

template <typename ClassType, typename ReturnType, typename... Args> 
struct is_const_func<ReturnType (ClassType::*)(Args...)> { 
    static const std::tuple<std::is_reference<Args>...> ref; 
    static const std::tuple<std::is_pointer<Args>...> ptr; 
    static const std::tuple<std::is_const<Args>...> con; 
    static const bool value = ? // Reduce(&&, (!ref && !ptr) || con) 
} 

我想知道如何實現value。基本上我想從每個元組中取第i個元素並計算(!ref[i] && !ptr[i]) || con[I],並在編譯時減少產生的元組&&

我該如何實施?有沒有更好的方法來做這個檢查?

+4

自由函數是什麼意思是const? – Barry

+0

在這種情況下,我正在檢查是否所有作爲參數傳入的指針和引用都是「const」限定的。這對於函數不改變程序狀態是不夠的,但我假定在函數中沒有訪問/改變全局變量。 – subzero

+2

你甚至可以用這樣的特質做什麼?除了全局狀態之外,傳遞給'T const *'還可能有一個被修改的'mutable'成員等,我們無法真正解決這個問題。 – Barry

回答

2

首先找到C++ 17 std apply的實現。

下一個寫all_of作爲constexpr模板函數。

接下來,編寫

struct all_of_t{ 
    constexpr all_of_t(){} 
    template<class...Bs> 
    constexpr bool operator()(Bs...bs)const{ return all_of(bs...); } 
}; 

最後:

static const std::tuple<std::integral_constant<bool, 
    (!std::is_reference<Args>{}&&!std::is_pointer<Args>{})||std::is_const<Args>{}>... 
> arg_state; 
static const bool value = apply(all_of_t, arg_state); 

每一步應該很容易搜索有關SO。

+0

與其將'all_of'寫爲'constexpr'函數,不如在C++ 17中使用'template constexpr bool all_of_v = Bs && ...;',或'template constexpr bool all_of_v = std :: is_same ,bools > :: value;'其中'bools'是一個像'template struct bools {};' – Justin

+1

@justin類型的類型我會讓這些不變的常量值不是布爾常量 – Yakk