声明模板函数以接受任何容器,但只接受一个包含类型

时间:2017-09-29 08:46:04

标签: c++ templates stl

我想声明一个接受不同STL容器的函数,但它们必须包含特定类的对象(例如,它应该接受std::vector<double>std::deque<double>但不接受std::vector<std::string>。 / p>

我找到了模板容器和包含类型的答案,但是我试图修改它们以便修复包含的类型是不成功的。

1 个答案:

答案 0 :(得分:7)

你可以使用模板模板参数(没有拼写错误)。模板函数的第一个模板参数是具有可变数量模板参数的另一个模板。第二个模板参数是可变参数模板参数。在签名中,然后将第一个模板参数修复为您想要的类型(例如double),并让编译器推断出其余部分。

#include <deque>
#include <iostream>
#include <string>
#include <vector>

template < template < class ... > class Container, class ... Args >
void any_container(Container<double, Args...>)
{
    // print what was deduced
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

int main()
{
    std::vector<double> vd;
    any_container(vd);

    std::deque<double> dd;
    any_container(dd);

    std::vector<std::string> vs;
    any_container(vs); // BOOM!
}

@PasserBy已经暗示了另一种解决方案in this comment。您也可以将容器作为模板参数,并在value_type中查询static_assert,而不是替换失败。这样做的好处是可以放置自定义错误消息。

#include <deque>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

template <typename Container> void any_container(Container)
{
    static_assert(std::is_same<typename Container::value_type, double>::value,
                  "BOOM!");
    // print what was deduced
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

int main()
{
    std::vector<double> vd;
    any_container(vd);

    std::deque<double> dd;
    any_container(dd);

    std::vector<std::string> vs;
    any_container(vs); // BOOM!
}