point vec<2>, foo(v1,p1) foo, vec<2>, . , , foo(const vec<2> &,const vec<2> &), .
, , , , point . ( , ).
, , , - :
template <typename T>
struct make_vec
{ };
template <unsigned d>
struct make_vec<vec<d>>
{
static constexpr unsigned dim = d;
using type = vec<dim>;
static const type &from(const type &v)
{ return v; }
};
template <>
struct make_vec<point>
{
static constexpr unsigned dim = 2;
using type = vec<dim>;
static type from(const point &p)
{ return type(p); }
};
template <typename T>
typename make_vec<typename std::decay<T>::type>::type make_vec_from(T&& arg)
{ return make_vec<typename std::decay<T>::type>::from(std::forward<T>(arg)); }
foo bar ( , vec<d>, make_vec, , vec<d>):
namespace detail {
template<unsigned d> vec<d> foo(vec<d>, vec<d>) {
return vec<d>();
}
}
template <typename T, typename... Ts>
typename make_vec<typename std::decay<T>::type>::type foo(T&& arg, Ts&&... args)
{ return detail::foo(make_vec_from(arg),make_vec_from(args)...); }
bar , vec<d1+d2+d3...>. , :
template <typename... Ts>
struct dsum {
static constexpr unsigned value = 0;
};
template <typename T, typename... Ts>
struct dsum<T,Ts...> {
static constexpr unsigned value = make_vec<typename std::decay<T>::type>::dim + dsum<Ts...>::value;
};
bar() vec<dsum<T,Ts...>::value>.
: http://liveworkspace.org/code/nZJYu$11
, , .