2017-07-10 76 views
1

在現代C++中面對constexpr修飾符的典型新手問題。struct member和boost :: hana :: filter

我說對了,即使在C++ 17中也沒有辦法編寫這樣的代碼(原因爲http://www.boost.org/doc/libs/1_63_0/libs/hana/doc/html/index.html#tutorial-appendix-constexpr)?

而且必須使用「值作爲類型」成語(在此示例中使用不同類型的打開和關閉文件)?

#include <boost/hana/filter.hpp> 
#include <boost/hana/tuple.hpp> 

namespace hana = boost::hana; 

enum class State { 
    Open, Closed 
}; 

struct File { 
    constexpr File(State state) : state_(state) {} 

    constexpr State state() const { return state_; } 

    const State state_; 
}; 

constexpr auto files = hana::make_tuple(File(State::Closed), File(State::Open)); 
constexpr auto filtered = hana::filter(files, [](const auto& file) { 
    return file.state() == State::Open; 
}); 

int main() { 
    return 0; 
} 
+0

我真的不知道該代碼的目的是什麼。 –

+0

我有一些結構的constexpr元組,我想在編譯時根據它們的成員字段來獲取它們的一些子集。 – yarrr

回答

1

在lambd你傳遞給hana::filter一個,你有兩個問題:

  1. file參數不constexpr
  2. 返回值是不是被hana::filter需要編譯時IntegralConstant轉換爲bool

保持元組constexpr在任何上下文中的一種方法是將它們包裝在constexpr lambdas中(在C++ 17中添加)。

下面的代碼解決了這兩個問題:

constexpr auto files = hana::make_tuple(
    []{ return File(State::Closed); } 
, []{ return File(State::Open); } 
); 

constexpr auto filtered = hana::filter(files, [](auto file) { 
    return hana::bool_c<file().state() == State::Open>; 
}); 
+0

這很棒,完全不直觀:你不能傳遞變量,但你可以傳遞lambda它返回這個var。謝謝! – yarrr

3

您需要的State編碼爲File的類型的一部分:

template <State TState> 
struct File 
{ 
    constexpr State state() const { return TState; } 
}; 

然後,你需要從你的過濾函數返回一個編譯時友好布爾:

constexpr auto files = hana::make_tuple(File<State::Closed>{}, File<State::Open>{}); 
constexpr auto filtered = hana::filter(files, [](const auto& file) 
{ 
    return hana::bool_c<decltype(file){}.state() == State::Open>; 
}); 

live example on wandbox

+0

是的,這就是我所說的「作爲一種類型的價值」。這很難過,如果只有選項:( – yarrr

+0

@yarr:你需要運行時還是編譯時計算? –

+0

只編譯時間 – yarrr

相關問題