如何根据容器的元素类型启用模板函数实例化

时间:2016-02-16 15:41:25

标签: c++ templates sfinae

我已经定义了容器检查结构及其实例化:

template <typename Container>
struct is_container : std::false_type { };

template<typename... Ts>
struct is_container<std::vector<Ts...>> : std::true_type { };

template<typename... Ts>
struct is_container<std::deque<Ts...>> : std::true_type { };

//... all other STL containers

对于像这样的功能模板,它几乎可以工作:

template<typename T, typename = typename std::enable_if<is_container<T>::value>::type>
void container_fun(const T& cont)
{
    std::cout << "argument is clearly a container!" << std::endl;
}

但是现在,我想根据容器的元素类型允许实例化。好吧,就像那样:

template<template<typename ...> class C , // container
         typename T, // container's element
         typename = typename std::enable_if<is_container<T>::value>::type> // permission
void is_element_container(const C<T>& cont)
{
    std::cout << "container's elemement is also a container!" << std::endl;
}

但是,这会导致错误:

.../main.cpp:10: error: no matching function for call to 'is_element_container(std::deque<int, std::allocator<int> >&)'
     is_element_container(deq);
                             ^
.../containers.h:36: error: no type named 'type' in 'struct std::enable_if<false, void>'
                  typename = typename std::enable_if<is_container<T>::value>::type>
                  ^

然而,删除第三个模板参数(权限检查)后:

template<template<typename ...> class C , // container
         typename T> // container's element

程序正常编译,功能打印输出。为什么会这样?

1 个答案:

答案 0 :(得分:2)

根据您的代码ceil(log2(M-1))要求is_element_container是一个容器作为模板参数。

但编译器抱怨C不是容器的容器,实际上并非如此。

就像你试图做的那样

std::deque<int>

但你似乎想要做

std::deque<int> cont;
is_element_container(cont);

这将允许模板扣除正确工作。