我正在尝试创建一个接受给定类型的多个参数的函数,但是应该通过模板指定参数的类型和数量。
我发现在这种情况下使用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");
}
};
答案 0 :(得分:6)
您无法静态断言运行时数量。 initializer_list
中的值的数量在运行时由函数的调用者决定。
甚至不能使你的函数constexpr
起作用,因为函数的评估不需要在编译时进行。
您应该使用可变参数模板。
答案 1 :(得分:2)
感谢Nicol,我展望了可变参数模板。问题不仅在于检查参数的数量,还要检查它们的类型是否可以转换为基类型。以下是基于this和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");
}
};
答案 2 :(得分:2)
添加POD类具有DIM数据成员的点最适合您的目的。然后隐式构造函数调用将确保一切正常。