首页
学习
活动
专区
圈层
工具
发布

C++模板
EN

Stack Overflow用户
提问于 2015-06-22 10:42:01
回答 3查看 280关注 0票数 4

我试图通过实现一个通用容器类来理解C++模板模板。以下是代码:

代码语言:javascript
复制
    using namespace std;

    template <typename T, template <typename STORETYPE> class Container>
    class Store {
    public:
        ~Store() {};
        Store() {};
        void someFunc( const T & ) {};
        //...
    private:
        Container<T> storage;
    };




    int main(int argc, char *argv[])
    {
        Store<int,deque> myStore;   // error here, won't compile!
    }

上面的代码生成编译器错误消息。错误信息是:

“模板参数具有与其对应的模板参数存储aStack1不同的模板参数;

我也不知道原因。怎么了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-22 10:47:01

您的问题是,std::deque (和其他标准容器)不只是一个模板参数。除了存储的类型外,还可以指定要使用的分配器函子类型。

如果您不关心这些附加参数,那么只需使用一个不同的模板就可以了:

代码语言:javascript
复制
template <typename T, template <typename...> class Container>
//                             variadic ^^^
class Store {

如果还希望支持将可选参数传递给容器类型,则可以这样转发它们:

代码语言:javascript
复制
template <template <typename ...> class Container, typename T, typename... ContainerArgs>
class Store {
    //...
    Container<T,ContainerArgs...> storage;
};

然后实例化如下:

代码语言:javascript
复制
Store<deque,int> myStore;
Store<deque,int,MyIntAllocator> mySpecialStore;

但是,您可能只想使用专门化提取模板参数:

代码语言:javascript
复制
template <typename Container>
class Store;

template <template <typename...> class ContainerType, typename T, typename... OtherArgs>
class Store<ContainerType<T,OtherArgs...>>
{
    //...
};

这将使客户端代码像这样实例化:

代码语言:javascript
复制
Store<deque<int>> myStore;
Store<deque<int,MyIntAllocator>> mySpecialStore;
Store<T> myOtherStore; //where T is some specialized container type
票数 6
EN

Stack Overflow用户

发布于 2015-06-22 10:53:56

std::deque被定义为

代码语言:javascript
复制
template <class T, class Allocator = allocator<T> > class deque;

因此,您应该更改Store的定义以匹配:

代码语言:javascript
复制
template <typename T, template <typename...> class Container>
class Store {

但实际上,您甚至不需要模板模板参数。只需将容器类型作为参数传递,就可以获得更多的通用性,例如,Storage将支持甚至std::map

代码语言:javascript
复制
template <typename  Container>
class Store {
public:
    using value_type = typename Container::value_type;
    ~Store() {};
    Store() {};
    void someFunc( const value_type& ) {};
    //...
private:
    Container storage;
};

Store<std::map<int, float>> myStore; 
票数 1
EN

Stack Overflow用户

发布于 2015-06-22 10:56:16

作为@TartanLlama回答的另一种选择,您还可以为deque使用别名。

代码语言:javascript
复制
template<typename T>
using deque_alias = deque<T>;

int main(int argc, char *argv[])
{
    Store<int,deque_alias> myStore;   // now it will compile!
}

然后,还正确使用默认模板参数(此处为std::allocator<T>)。(像MSVC这样的编译器有问题,否则会失败,因为他们需要两个模板参数,例如here )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30977899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档