【问题标题】:Declare "container" object from templated template class and variadic templates从模板化模板类和可变参数模板中声明“容器”对象
【发布时间】:2015-06-08 09:14:28
【问题描述】:

我需要声明一个可以存储不同类型容器的类。即如果它能够处理 std::bitset 和 std::array 那就太好了。 但是,这两个类需要不同的模板参数...... 是否可以(并且可能,如何)使用模板化模板类和可变参数模板来声明这种类?

示例(但错误):

template<template <typename..., std::size_t> class Container,
         std::size_t N,
         typename... Args>
class Base_Class
{
    ...
    Container<Args..., N/2> container;
};

编译器抱怨 N/2 不是一个类型。显然,对于 std::array 和 std::bitset 我都需要将大小作为最后一个模板参数...是否可以编写这种疯狂的代码?

谢谢!

编辑: 就我而言,主要问题是可变参数模板只能在右侧展开,因此可变参数必须是最后一个。任何人都知道是否有计划在 C++17 中允许以下语法?

template<typename... Args, typename T>
struct A
{};

【问题讨论】:

  • g++ 和 clang 都会出错(显然是 -std=c++11/14 参数)

标签: c++ templates c++11 variadic-templates template-templates


【解决方案1】:

Anton 的回答可以通过使用ResizedContainer 的规范的模板模板参数来减少容器特定

namespace detail {
    template<typename Container>
    struct ResizedContainer;

    template<template<typename,std::size_t> class Container,
             typename T, std::size_t N>
    struct ResizedContainer<Container<T,N>> {
        using type = Container<T,N/2>;
    };

    template<template<std::size_t> class Container,
             std::size_t N>
    struct ResizedContainer<Container<N>> {
        using type = Container<N/2>;
    };
}

#include <array>
#include <bitset>

template<typename Container>
class Base_Class {
    typename detail::ResizedContainer<Container>::type container;
};

int main() {
    Base_Class<std::array<int,4>> a;
    Base_Class<std::bitset<5>> b;
}

【讨论】:

    【解决方案2】:

    可能是这样的:

    namespace detail {
        template<typename Container>
        struct ResizedContainer;
    
        template<typename T, size_t N>
        struct ResizedContainer<std::array<T, N>> {
            using type = std::array<T, N/2>;
        };
    
        template<size_t N>
        struct ResizedContainer<std::bitset<N>> {
            using type = std::bitset<N/2>;
        };
    }
    
    template<typename Container>
    class Base_Class {
        typename detail::ResizedContainer<Container>::type container;
    };
    
    int main() {
        Base_Class<std::array<int, 4>> a;
        Base_Class<std::bitset<5>> b;
    }
    

    【讨论】:

    • 这个不错。无论如何,它是非常特定于容器的。有什么想法可以避免模板专业化并写下一个完整的通用模板类?
    • @dodomorandi 我认为你不能。 C++ 语法不允许这样做。
    • @AntonSavin C++ 语法不允许这样做。我怀疑你是对的,但你能“证明”吗?
    猜你喜欢
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    相关资源
    最近更新 更多