C++ 模板模板参数可以接受采用非类型参数的模板吗?

jac*_*bsa 6 c++ templates template-templates c++17 c++20

我有一个这样的函数要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);
Run Code Online (Sandbox Code Playgroud)

这个想法是使用模板模板参数 ( Container) 来允许接受任何类似 STL 的容器。我尝试过的实际 STL 中的所有内容都工作正常,但我们的代码库中的自定义容器不起作用,因为它接受非类型模板参数

template <typename Key, int Foo = 256>
class MyContainer;
Run Code Online (Sandbox Code Playgroud)

这会导致 clang 替换失败:

template template argument has different template parameters than its corresponding template template parameter
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以抽象所有模板参数,而不仅仅是类型?如果没有,是否有更好的方法来构建我的代码,以允许做我想做的事情,而无需专门为MyContainer所有其他人特别喜欢它?

Nel*_*eal 3

一个模板模板参数只能匹配一种模板;那种类型是由模板参数列表决定的。Fmap如果你想接受,你必须编写另一个版本MyContainer。但是,如果这样做,您可以匹配具有一个类型参数后跟任意数量的非类型参数的任何模板:它可以是int示例中的 a,也可以是 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 {};
}
Run Code Online (Sandbox Code Playgroud)

演示