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

Is there a way to check std::initializer_list number of arguments at 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"); 
    }
};

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

甚至使您的函数 constexpr 都行不通,因为不需要在编译时对函数求值。

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

感谢 , I looked towards the variadic templates. The problem was not only to check the number of arguments, but also to check that their types are convertible to the base type. Here's my solution based on and this 个主题。它在 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"); 
    }
};

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