如何为const和非const容器专门化模板?

时间:2014-06-15 20:48:06

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

我正在尝试对模板进行2次专业化:

  • 接受非常量容器的
  • 另一个接受const容器
  • 的人

我目前的代码是:

template<class T>
struct A{
    constexpr static int value=0;
};

template<template<typename>class T,typename...Args>
struct A<T<Args...>>{//accept non const containers
    constexpr static int value=1;
};

template<template<typename>class T,typename...Args>
struct A<T<Args...> const>{//accept const containers
    constexpr static int value=2;
};

ideone

但是该代码不起作用,如果我使用const容器,它使用第一个A的实例化而不是第三个。

using Type=const std::array<int,10>;
std::cout<<A<Type>::value;//output is 0

我尝试删除

template<class T>
struct A{
    constexpr static int value=0;
};

但它给了很多errors ..

我该怎么办?

3 个答案:

答案 0 :(得分:6)

我认为你可以在没有可变参数模板参数的情况下做到这一点:

template<class T>
struct A{
    constexpr static int value=0;
};

template<class T>
struct A<T const> {
    constexpr static int value=2;
};


int main()
{
    std::cout << A<const std::vector<int>>::value;
}

答案 1 :(得分:5)

您希望模板模板参数具有可变参数模板参数列表(所有标准容器实际上都有多个模板参数):

template< template<typename...> class T, typename...Args >
//                         ^^^

然后这段代码

#include <vector>
#include <iostream>

template<class T>
struct A{
    constexpr static int value=0;
};

template<template<typename...>class T,typename...Args>
struct A<T<Args...>>{//accept non const containers
    constexpr static int value=1;
};

template<template<typename...>class T,typename...Args>
struct A<T<Args...> const>{//accept const containers
    constexpr static int value=2;
};

int main()
{
    std::cout << A<const std::vector<int>>::value;
}

按预期输出2

但它仍然不能使用std::array,因为它在参数列表中包含一个非类型模板参数(并且它不能匹配一个可变参数类型的包)。我不能以通用的方式解决这个问题,我很害怕。

答案 2 :(得分:1)

始终使用type_traits。 http://en.cppreference.com/w/cpp/types/is_const

#include <type_traits>
#include <iostream>
#include <array>
#include <vector>

int main()
{
   std::cout << std::is_const< const std::vector<int> > ::value << '\n';
   std::cout << std::is_const< std::vector<int> >::value << '\n';

   std::cout << std::is_const< const std::array<int, 4> >::value << '\n';
   std::cout << std::is_const< std::array<int, 4> > ::value << '\n';
}

输出符合预期:

1
0
1
0