有没有办法在编译时检查std :: initializer_list参数的数量?

时间:2015-12-24 20:32:01

标签: c++ templates c++11 initializer-list compile-time

我正在尝试创建一个接受给定类型的多个参数的函数,但是应该通过模板指定参数的类型和数量。

我发现在这种情况下使用C ++ 11的 initializer_list 可能是一种很好的技术,但是有可能在编译时检查它的大小吗?还有其他技术可以解决这个问题吗?

#include <initializer_list>

// Here I want to define type and number of components for each point

template <typename T, int DIM>
class Geometry
{
public:
    void addPoint(std::initializer_list<T> coords)
    {
        assert(coords.size() == DIM); // Working good, but not compile-time

        // Next line does not compile because size() is not known at compile-time
        static_assert(coords.size() == DIM, "Wrong number of components"); 
    }
};

3 个答案:

答案 0 :(得分:6)

您无法静态断言运行时数量。 initializer_list中的值的数量在运行时由函数的调用者决定。

甚至不能使你的函数constexpr起作用,因为函数的评估不需要在编译时进行。

您应该使用可变参数模板。

答案 1 :(得分:2)

感谢Nicol,我展望了可变参数模板。问题不仅在于检查参数的数量,还要检查它们的类型是否可以转换为基类型。以下是基于thisthis主题的解决方案。它在GCC 4.9中按预期工作。

template<class T, class...>
struct are_convertible : std::true_type
{};

template<class T, class U, class... TT>
struct are_convertible<T, U, TT...>
    : std::integral_constant<bool, std::is_convertible<T,U>{} && are_convertible<T, TT...>{}>
{};

template <typename T, int DIM>
class Geometry
{
public:
    template<typename... Args>
    void addPoint(Args... coords)
    {
        static_assert(sizeof...(coords) == DIM, "Number of components does not match template");
        static_assert(are_convertible<T, Args...>{}, "All arguments' types must be convertible to the template type"); 
    }
};

答案 2 :(得分:2)

添加POD类具有DIM数据成员的点最适合您的目的。然后隐式构造函数调用将确保一切正常。