首页 > 解决方案 > C++ - 指定模板值类型

问题描述

我有这个功能

// Helper to determine whether there's a const_iterator for T.
template <typename T>
struct hasConstIt {
private:
    template<typename C> static char test(typename C::const_iterator*);
    template<typename C> static int test(...);
public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};

// Check if a container contains an element.
template <typename Container, typename = std::enable_if_t<hasConstIt<Container>::value> >
bool contains(const Container & container, typename Container::value_type const & element) {
    return std::find(container.begin(), container.end(), element) != container.end();
}

如何指定容器值类型必须是特定类型?假设我希望容器包含int,那么有效容器可能是vector<int>deque<int>等等。

标签: c++templates

解决方案


您可以使用std::is_same_vans来完成它static_assert

template <typename Container>
bool contains(const Container& container, typename Container::value_type const& element) {
    static_assert(std::is_same_v<typename Container::value_type, int>, "The container 'value_type' must be 'int'!");

    // You don't have to explicitly check if there is a 'const_iterator' because the STL containers specify 'cbegin()' and 'cend()'
    // which returns the 'Container::const_iterator'. So checking if these functions are there will be enough (for STL containers).
    return std::find(container.cbegin(), container.cend(), element) != container.cend();
}

现在如果Container::value_type不是int,它会抛出一个编译器错误,说明The container 'value_type' must be 'int'!

奖励:您hasConstIt可以用更好的方式编写(更具可读性,IDE 不会抱怨函数未定义),

template <typename T>
struct hasConstIt {
private:
    template<typename C> static constexpr bool test(typename C::const_iterator*) { return true; }
    template<typename C> static constexpr bool test(...) { return false; }
public:
    static constexpr bool value = test<T>(nullptr);
};

现在您可以使用另一个static_assert来检查是否有明确const_iterator的。Container此步骤是可选的。


推荐阅读