C ++如何生成函数重载的所有排列? [英] C++ how to generate all the permutations of function overloads?

查看:214
本文介绍了C ++如何生成函数重载的所有排列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有类日期和类

  struct Date {
日期(年年,月月,日):d(日),m(月),y(年){};
日期(月份,日期,年份):d(日期),m(月份),y(年份){};
日期(日期,月份,年份):d(日期),m(月份),y(年份){};
日期(日期,年份,月份):d(日期),m(月份),y(年份){};
...
...

私人:
第d天;
月m;
年y;
}

这使我不能有<$ c $

strong>



只是为了清楚起见:





  • 所有生成的重载都应该有相同的代码,只有
    布局

使用C ++ 14,你可以这样做:

  struct Date {
public:
Date(const Year& year,const Month& month,const日期&日):
d(日),m(月),y(年)
{}

模板< typename T1,typename T2,typename T3>
Date(const T1& t1,const T2& t2,const T3& t3):
Date(std :: get< Year>(std :: tie(t1,t2,t3)),
std :: get< Month>(std :: tie(t1,t2,t3)),
std :: get< Day> b $ b {}

private:
Day d;
月m;
年y;
};

编辑:
如果您还允许使用默认参数,您可以执行类似以下操作:

 命名空间详细信息
{
template< typename T,typename .. 。 struct has_T;

template< typename T> struct has_T< T> :std :: false_type {};

template< typename T,typename ... Ts> struct has_T :std :: true_type {};

template< typename T,typename Tail,typename ... Ts>
struct has_T< T,Tail,Ts ...> :has_T< T,Ts ...> {};

template< typename T,typename ... Ts>
const T& get_or_default_impl(std :: true_type,const std :: tuple< Ts ...& t,const T&)
{
return std :: get&
}

template< typename T,typename ... Ts>
const T& get_or_default_impl(std :: false_type,const std :: tuple< Ts ...>& const T& default_value)
{
return default_value;
}

template< typename T1,typename T2> struct is_included;

template< typename ... ts>
struct is_included< std :: tuple<>,std :: tuple< Ts ...>> :std :: true_type {};

template< typename T,typename ... Ts,typename ... Ts2>
struct is_included< std :: tuple< T,Ts ...>,std :: tuple< Ts2 ...>
:std :: conditional_t< has_T< T,Ts2 ...> :: value,is_included< std :: tuple< Ts ...> ;, std :: tuple< Ts2 ...> ;,std :: false_type> {};

}

template< typename T,typename ... Ts>
const T& get_or_default(const std :: tuple< Ts ...& t,const T& default_value = T {})
{
return detail :: get_or_default_impl< T& T,Ts ...> {},t,default_value);
}

然后

  struct Date {
public:
Date(const Year& year,const Month& month,const Day& day):
d (month),y(year)
{}

template< typename ... Ts,typename std :: enable_if_t< detail :: is_included< std :: tuple& 。>,std :: tuple< Year,Month,Day>> :: value> * = nullptr>
Date(const Ts& ... ts):
Date(get_or_default< const Year&>(std :: tie(ts ...)),
get_or_default& >(std :: tie(ts ...)),
get_or_default< const Day&>(std :: tie(ts ...)))
{}
b $ b private:
Day d;
月m;
年y;
};

实时演示

无效构造函数调用的实时演示


Lets say I have classes Date and classes Year, Month and Day.

struct Date {
  Date(Year year, Month month, Day day) : d(day), m(month), y(year) {};
  Date(Month month, Day day, Year year) : d(day), m(month), y(year) {};
  Date(Day day, Month month, Year year) : d(day), m(month), y(year) {};
  Date(Day day, Year year, Month month) : d(day), m(month), y(year) {};
  ...
  ...

  private:
    Day d;
    Month m;
    Year y;
}

This allows me not to have a specific layout of arguments for Date as I have a lot of overloadings.

Am I able to generate all the permutations/overloadings automatically?

Just to be clear:

  • Permutations are only of argument layout, nothing about them should change as I know that would not be possible to automate.
  • All the generated overloadings should have the same code as only the layout of arguments changes not the logic itself.

解决方案

With C++14, you may do:

struct Date {
public:
    Date(const Year& year, const Month& month, const Day& day) :
        d(day), m(month), y(year)
    {}

    template <typename T1, typename T2, typename T3>
    Date(const T1& t1, const T2& t2, const T3& t3) : 
        Date(std::get<Year>(std::tie(t1, t2, t3)),
             std::get<Month>(std::tie(t1, t2, t3)),
             std::get<Day>(std::tie(t1, t2, t3)))
    {}

private:
    Day d;
    Month m;
    Year y;
};

Edit: if you would also allow default argument, you may do something like:

namespace detail
{
    template <typename T, typename... Ts> struct has_T;

    template <typename T> struct has_T<T> : std::false_type {};

    template <typename T, typename... Ts> struct has_T<T, T, Ts...>
    : std::true_type {};

    template <typename T, typename Tail, typename... Ts>
    struct has_T<T, Tail, Ts...> : has_T<T, Ts...> {};

    template <typename T, typename... Ts>
    const T& get_or_default_impl(std::true_type, const std::tuple<Ts...>& t, const T&)
    {
        return std::get<T>(t);
    }

    template <typename T, typename... Ts>
    const T& get_or_default_impl(std::false_type, const std::tuple<Ts...>&, const T& default_value)
    {
        return default_value;
    }

    template <typename T1, typename T2> struct is_included;

    template <typename... Ts>
    struct is_included<std::tuple<>, std::tuple<Ts...>> : std::true_type {};

    template <typename T, typename... Ts, typename ... Ts2>
    struct is_included<std::tuple<T, Ts...>, std::tuple<Ts2...>>
        : std::conditional_t<has_T<T, Ts2...>::value, is_included<std::tuple<Ts...>, std::tuple<Ts2...>>, std::false_type> {};

}

template <typename T, typename... Ts>
const T& get_or_default(const std::tuple<Ts...>& t, const T& default_value = T{})
{
    return detail::get_or_default_impl<T>(detail::has_T<T, Ts...>{}, t, default_value);
}

And then

struct Date {
public:
    Date(const Year& year, const Month& month, const Day& day) :
        d(day), m(month), y(year)
    {}

    template <typename ... Ts, typename std::enable_if_t<detail::is_included<std::tuple<Ts...>, std::tuple<Year, Month, Day>> ::value>* = nullptr>
    Date(const Ts&... ts) :
        Date(get_or_default<const Year&>(std::tie(ts...)),
             get_or_default<const Month&>(std::tie(ts...)),
             get_or_default<const Day&>(std::tie(ts...)))
    {}

private:
    Day d;
    Month m;
    Year y;
};

Live Demo
Live Demo with invalid constructor call

这篇关于C ++如何生成函数重载的所有排列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆