我有一個這樣的函式可以fmap為 C 實作:
// Given a mapping F from T to U and a container of T, return a container of U
// whose elements are created by the mapping from the original container's
// elements.
template <typename F, template <typename...> typename Container, typename T>
Container<std::invoke_result_t<F&, const T&>> Fmap(F&& f,
const Container<T>& input);
這個想法是使用模板模板引數 ( Container) 來允許接受任何類似 STL 的容器。我嘗試過的實際 STL 中的所有這些都可以正常作業,但是我們代碼庫中的自定義容器不起作用,因為它接受非型別模板引數
template <typename Key, int Foo = 256>
class MyContainer;
這會導致 clang 的替換失敗:
template template argument has different template parameters than its corresponding template template parameter
有沒有辦法抽象所有模板引數,而不僅僅是型別?MyContainer如果沒有,是否有更好的方法來構建我的代碼以允許在不專門針對所有其他人特別喜歡它的情況下做我想做的事情?
uj5u.com熱心網友回復:
一個模板模板引數只能匹配一種模板;該種類由模板引數串列確定。Fmap如果你想接受,你必須寫另一個版本MyContainer。但是,如果您這樣做,您可以匹配具有一個型別引數后跟任意數量的非型別引數的任何模板:它可以是int您示例中的類似,或者它可以是 achar和 a bool...
template <typename F, template <typename, auto...> typename Container, typename T, auto ...Vs>
Container<std::invoke_result_t<F&, const T&>, Vs...> Fmap(F&& f, const Container<T, Vs...>& input) {
return {};
}
演示
uj5u.com熱心網友回復:
為了補充已經給出的一般建議(每個容器的多載),我認為您可以通過探索Louis Dionne的Boost.Hana定義和其他概念的方式來很好地了解一種方法可以完成的事情(是的,還有,和其他),以及型別如or (編譯時可選)如何實作它。FunctorApplicativeMonadComonadboost::hana::basic_tupleboost::hana::optional
另一個可以拓寬您對該主題的看法的有趣讀物是P1895,Barry Revzin關于該主題的帖子也很喜歡它(不完全贊成鏈接提案所涉及的方法)。tag_invoke
前段時間,我也問了一個關于這個話題的問題,但還沒有得到滿意的答復。
uj5u.com熱心網友回復:
由于您的函式不知道模板模板引數的模板引數型別,并且無法使用它們,因此它們都必須在實際模板引數中具有默認值。您可以通過創建和使用別名模板來利用這一事實:
template <typename F, template <typename /* no pack */> typename Container, typename T>
Container<std::invoke_result_t<F&, const T&>> Fmap(F&& f,
const Container<T>& input);
template <typename X> using MyContainerDefault = MyContainer<X>;
something = Fmap(someFunction, MyContainerDefault);
話雖如此,標準庫演算法不接受或回傳容器是有充分理由的。有很多資源可以解釋這一點,只需搜索why stl algorithms do not work with containers.
另一點值得一提的是,在 Haskell 中,每個“容器”(函子)fmap都以自己的方式實作,所以一個通用的實作Fmap是相當可疑的。如果要克隆fmap,它應該對每個容器都有一個多載,或者是容器的成員函式。一旦您接受這一點,您就不再需要模板模板引數,因為每個容器都知道自己的模板引數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/526406.html
下一篇:RAM、存盤單元和地址
