2016-12-04 75 views
1

documentation對於hana::keys說我可以在函數調用語法中使用它,例如hana::keys(s)其中s是符合概念hana::Struct的類的一個實例,它返回一系列關鍵對象。我可以在沒有結構實例的情況下使用`hana :: keys`嗎?

相關函數hana::accessors返回可用於從結構實例中獲取相應成員的訪問函數序列。

hana::accessorscan be used in two ways

hana::accessors(s) 
hana::accessors<S>() 

都是合法的,constexpr函數時S = decltype(s)返回同樣的事情 - 序列對應於結構S

當我用hana::keys嘗試此語法時,出現錯誤。下面是一個MCVE,適應於hana文件從一個例子:


#include <boost/hana.hpp> 
#include <boost/hana/define_struct.hpp> 
#include <boost/hana/keys.hpp> 
#include <iostream> 
#include <string> 

namespace hana = boost::hana; 

struct Person { 
    BOOST_HANA_DEFINE_STRUCT(Person, 
     (std::string, name), 
     (unsigned short, age) 
    ); 
}; 


// Debug print a single structure 

template <typename T> 
void debug_print_field(const char * name, const T & value) { 
    std::cout << "\t" << name << ": " << value << std::endl; 
} 


template <typename S> 
void debug_print(const S & s) { 
    std::cout << "{\n"; 

    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
    debug_print_field(hana::to<char const *>(key), hana::at_key(s, key)); 
    }); 

    std::cout << "}" << std::endl; 
} 

// Debug print compare two structures 

int main() { 
    Person john{"John", 30}, kevin{"Kevin", 20}; 

    debug_print(john); 
    std::cout << std::endl; 
    debug_print(kevin); 
    std::cout << std::endl; 
} 

$ g++-6 -std=c++14 -I/home/chris/boost/boost_1_61_0/ main.cpp 
main.cpp: In function ‘void debug_print(const S&)’: 
main.cpp:28:30: error: expected primary-expression before ‘>’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
          ^
main.cpp:28:32: error: expected primary-expression before ‘)’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
           ^

它,當我使用hana::keys(s)工作正常。

但在我的實際應用中,我沒有結構的實例,它只是一個模板參數。

一劈,我做了這個:

// Work around for `hana::keys` 

template <typename S> 
constexpr decltype(auto) get_hana_keys() { 
    return decltype(hana::keys(std::declval<S>())){}; 
} 

相信這個作品基於我有限的實況描述hana實現細節的理解。 - hana::keys應該返回一個編譯時字符串序列,並且所有信息都包含在該類型中,所以獲取類型和默認構造它應該是等效的。

當我在我的MCVE中使用get_hana_keys<S>()時,它編譯並運行正常。

但是我不知道它是否真的正確,或者我所做的假設超出了文檔允許我假設的範圍。

我正在使用增強版本1.61gcc 6.2.0

我想知道的是什麼,

  • 是否有一個很好的理由,hana::keys<S>()不工作或者是這只是一個疏忽? hana似乎已經非常精心設計,所以我傾向於在這裏猜測自己。

  • 我創建的破解或改進方法有什麼問題嗎?

回答

2

好問題!

hana::keys<S>()有沒有很好的理由,或者這只是一個疏忽?

hana::keys<S>()不起作用的原因是在一般情況下無法實現它。實際上,keys最初設計爲hana::map,其中密鑰可能爲爲有狀態,因此您確實需要一個對象才能返回有意義的對象。事實上,一個對象不需要檢索hana::Struct的密鑰,這只是一個巧合。

我創建的破解或改進方法有什麼問題嗎?

技術上,hana::string沒有記錄爲默認構造的,所以默認情況下,這些建設的hana::tuple不能保證正常工作。但是,這是我在1eebdb中修復的一個疏忽,所以你很好。

話雖這麼說,一個也許更地道的解決辦法是以下幾點:

template <typename S> 
constexpr auto get_hana_keys() { 
    return hana::transform(hana::accessors<S>(), hana::first); 
} 

其實,這就是我們如何界定hana::keyshana::Struct秒。

最後,請注意,所有與hana::Struct相關的東西都會更好地通過語言層面的反思,所以請原諒對Hana提供反思的古怪支持。在沒有語言支持的情況下,在這方面做任何事情都很難。

相關問題