如何将模板类的名称传递给模板参数?

3

我知道我们可以完成以下操作:

template <class CONTAINER>
void f(CONTAINER *c){}

int main(){
    std::vector<int> v;
    f(&v);
    std::set<int> s;
    f(&s);
}

然后,我希望有一个替代方案(适合我的项目),就像以下内容一样:
template <class CONTAINER>
void f(CONTAINER<int> *c){} // the CONTAINER is the name of a template class

但是,编译器输出

error: ‘CONTAINER’ is not a template

你能行吗?


它被称为模板模板参数 - Thomas Sablik
结合可变模板参数,它可以非常优雅。 - WhozCraig
1个回答

4
你正在寻找一个模板模板参数:

您正在寻找模板模板参数

#include <set>
#include <vector>

template<template<typename> typename CONTAINER>
void f(CONTAINER<int> *){}

int main(){
    std::vector<int> v;
    f(&v);
    std::set<int> s;
    f(&s);
}

"将匹配的模板模板参数与兼容的参数相匹配" 是C++17的一个功能。这在C++14中不起作用,因为std::vector有多个模板参数。
使用-frelaxed-template-template-args来编译此代码需要Clang,请参见:Template template parameter in function templatesHow is P0522R0 breaking code? 另一种方法是使用变长模板的模板模板参数来避免"Matching template template parameters to compatible arguments":
#include <set>
#include <vector>

template<class T, template<class, class...> class CONTAINER, class... Args>
void f(CONTAINER<T, Args...> *){}

int main(){
    std::vector<int> v;
    f(&v);
    std::set<int> s;
    f(&s);
}


#include <set>
#include <vector>

template<template<class, class...> class CONTAINER, class... Args>
void f(CONTAINER<int, Args...> *){}

int main(){
    std::vector<int> v;
    f(&v);
    std::set<int> s;
    f(&s);
}

这适用于 C++11。


你可能想要尝试编译它。 - WhozCraig
@WhozCraig 我在发布之前尝试了:https://wandbox.org/permlink/9vMIp3jRzDentnde 在GCC和Clang之间有不同的行为:https://stackoverflow.com/questions/62884147/template-template-parameter-in-function-templates 和 https://dev59.com/xVYN5IYBdhLWcg3whYi3 - Thomas Sablik
我使用clang和-std=c++14,所以这会在多个方面出现问题。在CONTAINER之前不允许使用typename,但可以使用class,正如你所说,带有附加默认参数的类的部分匹配也行不通(但是可变参数规范也可以解决这个问题)。 - WhozCraig
1
是的,我只是使用template < class T, template <class, class...> class CONTAINER, class... Args> void f(CONTAINER<T, Args...> *){},因为它可以在C++11中适用于所有内容,而无需其他标志。 - WhozCraig
1
不用了,你的方法对我很有效。老实说,我甚至不知道这个问题在17中得到了解决。在14之后,我就没有再关注标准更新了,毕竟我是工程师。学到了新东西,谢谢! - WhozCraig
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接